# Nginx Proxy_Pass Error
The proxy_pass directive connects Nginx to upstream servers, but misconfigured URLs cause 502 errors, wrong paths, or failed connections. A trailing slash makes the difference between correct proxying and broken routing. Understanding how Nginx constructs the proxied URL is essential.
Introduction
This article covers troubleshooting steps and solutions for How to Fix Nginx Proxy_Pass Error. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.
Symptoms
Common error messages include:
location /api/ {
proxy_pass http://backend/v1/;
}location /api/ {
proxy_pass http://backend;
}location /api/ {
proxy_pass http://backend:3000;
}Common Causes
- Configuration misconfiguration
- Missing or incorrect credentials
- Network connectivity issues
- Version compatibility problems
- Resource exhaustion or limits
- Permission or access denied
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Understanding Proxy_Pass URL Construction
- 1.
proxy_passcombines two parts: - 2.The location match
- 3.The proxy_pass URL
URL construction rules:
- If proxy_pass has URI path: replace location match with proxy_pass path
- If proxy_pass has no URI path: append request URI to proxy_pass
Example 1 - proxy_pass with path:
``nginx
location /api/ {
proxy_pass http://backend/v1/;
}
Request /api/users becomes http://backend/v1/users`
Example 2 - proxy_pass without path:
``nginx
location /api/ {
proxy_pass http://backend;
}
Request /api/users becomes http://backend/api/users`
Common Cause 1: Trailing Slash Mismatch
Trailing slashes drastically change behavior.
Problematic config:
``nginx
location /api/ {
proxy_pass http://backend:3000;
}
Request /api/users:
- Location captures /api/
- Remaining URI: users
- proxy_pass has no path (no trailing slash)
- Full proxy URL: http://backend:3000/api/users
Backend receives /api/users. If backend expects /users, this fails.
Solution - add trailing slash:
``nginx
location /api/ {
proxy_pass http://backend:3000/;
}
Request /api/users:
- Location captures /api/
- proxy_pass path: /
- Remaining URI: users
- Proxy URL: http://backend:3000/users
Backend receives /users - correct.
| Config | Request | Backend Receives |
|---|---|---|
proxy_pass http://backend; (no slash) | /api/users | /api/users |
proxy_pass http://backend/; (slash) | /api/users | /users |
proxy_pass http://backend/v1/; | /api/users | /v1/users |
Common Cause 2: Location Without Trailing Slash
Location without trailing slash changes matching behavior.
Problematic config:
``nginx
location /api {
proxy_pass http://backend/;
}
Request /api/users:
- Location /api matches prefix
- Nginx doesn't strip /api from URI
- proxy_pass path / replaces nothing
- Proxy URL: http://backend/api/users
Solution: Add trailing slash to location:
``nginx
location /api/ {
proxy_pass http://backend/;
}
Common Cause 3: Regex Location with Proxy_Pass
Regex locations can't use path replacement in proxy_pass.
Problematic config:
``nginx
location ~ ^/api/(.*)$ {
proxy_pass http://backend/$1;
# Invalid - can't use capture groups in proxy_pass directly
}
Nginx error:
``
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression
Solution: Use rewrite or map:
``nginx
location ~ ^/api/(.*)$ {
set $path $1;
proxy_pass http://backend/$path;
}
Or use prefix location:
``nginx
location /api/ {
proxy_pass http://backend/;
}
Common Cause 4: Upstream DNS Resolution
proxy_pass with hostname requires DNS resolution.
Problematic config:
``nginx
location / {
proxy_pass http://api.example.com;
}
If DNS changes IP, Nginx keeps old IP until reload.
Solution: Use resolver directive:
``nginx
location / {
resolver 8.8.8.8 valid=30s;
set $upstream http://api.example.com;
proxy_pass $upstream;
}
Or use upstream block: ```nginx upstream api { server api.example.com resolve; # Nginx Plus feature }
location / { proxy_pass http://api; } ```
Common Cause 5: Wrong Protocol
HTTP vs HTTPS mismatch with upstream.
Problematic config:
``nginx
location / {
proxy_pass http://backend:443;
# Backend expects HTTPS on 443
}
Upstream receives HTTP on HTTPS port - connection fails.
Solution: Use correct protocol:
``nginx
location / {
proxy_pass https://backend:443;
proxy_ssl_verify off; # For self-signed certificates
}
Common Cause 6: Missing Port
proxy_pass without port uses default (80 for HTTP, 443 for HTTPS).
Problematic config:
``nginx
location / {
proxy_pass http://backend;
# Uses port 80, backend listens on 3000
}
Solution: Specify port:
``nginx
location / {
proxy_pass http://backend:3000;
}
Common Cause 7: Upstream Block vs Direct URL
Mixing upstream block syntax with direct URL.
Problematic config: ```nginx upstream backend { server 10.0.0.1:3000; }
location /api/ { proxy_pass http://backend:3000/; # backend is upstream name, not host # Actually works, but confusing } ```
Solution: Use consistent approach: ```nginx upstream backend_servers { server 10.0.0.1:3000; server 10.0.0.2:3000; }
location /api/ { proxy_pass http://backend_servers/; } ```
Or direct:
``nginx
location /api/ {
proxy_pass http://10.0.0.1:3000/;
}
Common Cause 8: Path Encoding Issues
URL encoding handled differently by Nginx and backend.
Problematic config:
``nginx
location /api/ {
proxy_pass http://backend/;
}
Request /api/search?q=hello%20world:
- %20 is space
- Some backends expect decoded URL
Solution: Control encoding:
``nginx
location /api/ {
proxy_pass http://backend/;
proxy_set_header X-Original-URI $request_uri;
}
Backend can receive both encoded and decoded variants.
Common Cause 9: IPv6 Address Syntax
IPv6 addresses need brackets in proxy_pass.
Problematic config:
``nginx
location / {
proxy_pass http://::1:3000; # Invalid syntax
}
Solution: Use brackets:
``nginx
location / {
proxy_pass http://[::1]:3000;
}
Verification
- 1.Test proxy_pass URL:
- 2.```bash
- 3.curl -v http://localhost/api/users 2>&1 | grep ">"
- 4.
` - 5.Check upstream receives:
- 6.```bash
- 7.# On backend server
- 8.tail -f /var/log/backend/access.log
- 9.
` - 10.Add diagnostic header:
- 11.```nginx
- 12.location /api/ {
- 13.proxy_pass http://backend/;
- 14.add_header X-Proxied-URL $upstream_uri always;
- 15.}
- 16.
` - 17.Test configuration:
- 18.```bash
- 19.sudo nginx -t
- 20.
` - 21.Check error log:
- 22.```bash
- 23.tail -f /var/log/nginx/error.log
- 24.
` - 25.Verify backend connection:
- 26.```bash
- 27.# Test backend directly
- 28.curl http://backend:3000/users
- 29.
`
Complete Working Configurations
Simple proxy:
``nginx
location /api/ {
proxy_pass http://backend:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
With upstream block: ```nginx upstream backend { server 10.0.0.1:3000; server 10.0.0.2:3000 backup; keepalive 32; }
location /api/ { proxy_pass http://backend/; proxy_http_version 1.1; proxy_set_header Connection ""; } ```
With path rewrite:
``nginx
location /old-api/ {
rewrite ^/old-api/(.*)$ /v1/$1 break;
proxy_pass http://backend:3000/;
}
Dynamic upstream: ```nginx location /api/ { resolver 8.8.8.8 valid=30s;
set $upstream_host api.example.com; proxy_pass http://$upstream_host/; } ```
Verification
| Config | Request | Backend URL |
|---|---|---|
location /api/ { proxy_pass http://backend; } | /api/users | /api/users |
location /api/ { proxy_pass http://backend/; } | /api/users | /users |
location /api/ { proxy_pass http://backend/v1/; } | /api/users | /v1/users |
location /api { proxy_pass http://backend/; } | /api/users | /api/users |
location ~ ^/api/(.*)$ { proxy_pass http://backend/$1; } | Invalid! | Use set variable |
The critical rule: trailing slash on proxy_pass strips the location prefix; no trailing slash preserves it. Match your location and proxy_pass slashes to what the backend expects.
Related Articles
- [Nginx troubleshooting: Fix Lambda Permission Denied - Complete ](fix-lambda-permission-denied)
- [Nginx web server troubleshooting: Fix Client Max Body Size Large Upload Nginx Issue ](client-max-body-size-large-upload-nginx)
- [Fix Apache 502 Proxy Error](fix-apache-502-proxy-error)
- [Fix Apache LogLevel Core Debug Configuration](fix-apache-loglevel-core-debug)
- [Fix Cloudflare 502 Bad Gateway Error](fix-cloudflare-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "How to Fix Nginx Proxy_Pass Error", "description": "Troubleshoot Nginx proxy_pass directive errors. Fix URL parsing, path mapping, and upstream resolution issues.", "url": "https://www.fixwikihub.com/fix-nginx-proxy-pass-error", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-28T07:01:27.373Z", "dateModified": "2025-11-28T07:01:27.373Z" } </script>