Nginx 502 Bad Gateway: trace the upstream before changing timeouts
A 502 is an upstream connectivity or response problem. Establish whether the backend is reachable, alive, and responding within its budget before changing proxy settings.
Maintained by Kevin · Ovalk
Scope and prerequisites
Nginx reverse proxy on Linux with an HTTP or HTTPS upstream. FastCGI and gRPC use different directives.
Know the upstream address, service owner and failing request path. Read access to proxy logs is required; nginx -T can reveal sensitive configuration.
Common symptoms
- Browsers or a load balancer return HTTP 502.
- Nginx logs show connection refused, connect() failed, or upstream timed out.
- One route, one backend instance, or the whole service is affected.
1. Scope the blast radius
Call the upstream health endpoint from the Nginx host and identify whether the failure is limited to a single backend. Remove an unhealthy instance from traffic before restarting the whole tier.
curl -sv http://127.0.0.1:8080/health
ss -lntp | grep 8080
tail -n 100 /var/log/nginx/error.log2. Separate connection errors from response timeouts
Connection refused usually means a missing listener, exited process, or wrong target. Read the full timeout phrase: “while connecting” and “while reading” identify different stages. A timeout does not prove TCP connected; gateway timeouts commonly return 504. Investigate the indicated stage before adjusting a timeout.
grep -E "connect|upstream timed out" /var/log/nginx/error.log | tail -n 30
systemctl status your-app.service --no-pager3. Verify the proxy contract
Check the upstream address, path handling, DNS result, protocol and—when HTTPS is used—SNI and certificate configuration. Validate from inside the proxy container in containerized deployments.
nginx -T | sed -n "/proxy_pass/p"
getent hosts backend.internalInterpret the evidence
| Observation | What to check next |
|---|---|
| Connection refused | Check the exact upstream IP, port and listener. A firewall may also actively reject a connection. |
| Timeout while connecting / while reading | Connecting and reading are different stages. Read the complete log phrase; a timeout need not mean TCP succeeded, and a gateway timeout often appears as 504. |
| Upstream works directly; proxy path fails | Compare Host, URI rewriting, protocol and HTTPS SNI before changing application capacity. |
Illustrative diagnosis
A hypothetical example to explain the reasoning, not a reported customer incident or a claim of testing on your stack.
A proxy returns 502 just after an application release. Its error log names 127.0.0.1:8080, while the application now listens on 8081. A longer timeout cannot repair that mismatch. Compare the intended deployment contract with both listeners, restore the approved address or application setting, and check the same request through the proxy.
Verify recovery
- Repeat the original failing path through the public hostname, checking both status and response content. An unrelated /health endpoint alone is insufficient.
- Compare upstream errors and latency across every backend during representative traffic; one successful retry may only have selected a healthy peer.
Rollback and stopping point
Save the previous proxy configuration before editing. If nginx -t fails, do not reload. If errors increase after a validated reload, restore the prior configuration and revalidate; do not reintroduce a known-bad backend.
Prevention and long-term repair
- Use per-upstream health checks and safe traffic-draining.
- Monitor request duration, queue depth and application latency alongside status codes.
- Test the production-equivalent proxy path in every release.
References and corrections
Use the documentation for your installed version. The references below explain the underlying behavior; commands still need environment-specific validation.
Report a correction to Kevin — include the page URL, version and a redacted reproduction. See our editorial policy.