Gary VirkIT Specialist
← All work

08 Systems support · HTTP · Nginx

Tracing an HTTP 502 through a reverse proxy

The proxy is reachable and the backend is healthy. The error log points to one incorrect upstream port.

Issue
The proxy is reachable but returns 502. Is the backend unhealthy, or is the proxy trying the wrong upstream address or port?
Decisive evidence
The backend health endpoint passed directly while the proxy returned 502 and logged a refused connection to port 9090.E01
Result
A client-facing 502 does not prove the application is down. Direct upstream health and proxy configuration must be checked separately.
Boundary
This is one internal Docker network and one HTTP health endpoint.Full limit
Completion
Complete within stated scope
Execution
Isolated proxy and backend run
Review
Scripted assertions and artifact check
Evidence
Selected evidence on this page
  • Nginx 1.29
  • Python HTTP server
  • Docker internal network
  • ARM64

The proxy is reachable but returns 502. Is the backend unhealthy, or is the proxy trying the wrong upstream address or port?

Project record: An isolated proxy and backend, an incorrect upstream port, the 502 and connection-refused log, a one-line correction, and a repeated health request.

Check the service path one hop at a time.

The backend stays healthy while the proxy points to the wrong port. Only the upstream hop changes.

Choose a view

The backend answers on port 8081 before the proxy is changed.

  1. 01
    ClientHealth request
  2. 02
    Nginx proxyReachable
  3. 03
    Upstream port9090 or 8081
  4. 04
    BackendHealthy on 8081

Check the backend directly before changing the proxy.

  1. 01

    Start a small backend health endpoint and confirm it returns the expected response directly.

  2. 02

    Point the proxy at a different, closed upstream port and repeat the same client request.

  3. 03

    Read the proxy configuration and error log together instead of restarting both services.

  4. 04

    Correct only the upstream port, recreate the proxy, and run two successful health requests.

The checks used to reach the conclusion.

Selected outputs from the lab. Sensitive and unnecessary details are omitted.

service=inventory-api status=healthy
E01 · Captured lab outputDirect backend checkThe application responds directly before any proxy change is made.
HTTP/1.1 502 Bad Gateway
E02 · Captured lab outputClient-facing failureThe same health request through the proxy returns HTTP 502.
connect() failed (111: Connection refused)
upstream: http://[isolated-lab-address]:9090/health
E03 · Captured lab outputUpstream refusalThe proxy log identifies a refused connection to the configured upstream port 9090.
Full evidence archive3 additional artifacts
before: proxy_pass http://backend:9090/health;
after : proxy_pass http://backend:8081/health;
E04 · Captured lab outputOne-line correctionThe proxy target changes from the closed port 9090 to the backend’s actual port 8081.
HTTP/1.1 200 OK
service=inventory-api status=healthy
E05 · Captured lab outputCorrection resultThe request through the corrected proxy returns the backend health line.
HTTP/1.1 200 OK
service=inventory-api status=healthy
E06 · Captured lab outputSeparate retestA second request after correction returns the same expected health response.

What changed, and what this lab does not prove.

Result

The backend returned healthy while the proxy returned 502 and logged connection refused to port 9090. Pointing the proxy to the backend’s actual port 8081 returned HTTP 200 and the expected health response in the correction and separate retest.

Limit

This is one internal Docker network and one HTTP health endpoint. It does not test public DNS, TLS termination, load balancing, authentication, or production service ownership.

What the evidence supports.

The backend health endpoint passed directly while the proxy returned 502 and logged a refused connection to port 9090.

The failure covers one inserted upstream-port error.

EvidenceE01E02E03
Changing the upstream port to 8081 returned HTTP 200 and the expected health response in the correction and separate retest.

The successful result covers one local health route.

EvidenceE04E05E06