Server

HTTP 502

Also called Bad Gateway.

HTTP 502 is the proxy or gateway telling the client that the server behind it sent back a bad or empty reply. The proxy is alive. The upstream is not answering properly.

How it is measured

Read the proxy error log, which is where the cause appears. Nginx writes lines like 'connect() failed (111: Connection refused) while connecting to upstream' or 'upstream prematurely closed connection'. Count 502 per minute against the total requests.

A steady trickle of 502 often means a worker crashed mid-request. A wall of them for 30 seconds means the upstream process was down, restarting or deploying.

Worked example

A Node app behind Nginx is restarted by a deploy script that stops the old process before the new one listens on port 3000. For the 6 seconds between, every request through Nginx gets 502, around 190 requests in total.

Switching to a rolling restart where the new process starts first, together with a health check on the balancer, brings 502 count during deploys to zero. The proxy was fine throughout. The upstream gap was the issue.

How it differs

HTTP 502 is a bad answer from upstream, or none at all. HTTP 504 is an answer that never came before the proxy's timeout. A 502 excludes a pure timeout, since something was received or refused. A 504 excludes a refused connection. Reading the proxy log separates them in seconds.

Common errors

Restarting the proxy when the upstream is the broken part. Looking only at the app log, which may contain nothing. Assuming TLS is the cause when the proxy talks plain HTTP to upstream. Confusing a Cloudflare 502 with an origin 502. Ignoring a crashed PHP-FPM or Node process behind the proxy.

In practice

Next time you see 502, read the proxy error log first, then check that the upstream process is running and listening on the expected socket. Add a deploy step that waits for the new process to pass a health check before the old one stops.

See also

HTTP 503, HTTP 504

Sources

Count this on a real site.

Watch my website