HTTP 502 Bad Gateway Explained
Learn what HTTP 502 Bad Gateway means, how it differs from 500 and 504, what causes a proxy to return it, and how to diagnose and fix it.
A 502 is not your application saying it failed. It is a proxy in front of your application saying it could not get a usable answer out of it. That distinction is the whole diagnosis: two different machines are involved, and the one reporting the error is not the one that has the problem.
1. What Does HTTP 502 Mean?
502 Bad Gateway indicates that a server acting as a gateway or proxy received an invalid response from the upstream server it contacted.
- Key idea: the proxy reached the upstream but could not use what came back.
- Mechanism: a reverse proxy β Nginx, HAProxy, a cloud load balancer, a CDN β forwards your request, and the backend returns garbage, closes the connection, or refuses it outright.
- Who emits it: the proxy, never the application. Your application code cannot produce a 502 for its own request.
The response you see comes from infrastructure that is working correctly and reporting a failure elsewhere.
2. Common Causes
The backend is down. Nothing is listening on the port the proxy forwards to. Common during restarts, failed deploys, or crash loops.
The backend crashed mid-request. The process died while responding, so the proxy received a truncated or empty response.
The backend closed the connection early. Worker timeouts, out-of-memory kills, or a process manager reaping a worker mid-response.
Protocol mismatch. The proxy speaks HTTP to something expecting HTTPS, or forwards HTTP/2 to a backend that only speaks HTTP/1.1. The bytes arrive; they simply do not parse.
Response too large for proxy buffers. Nginx with undersized proxy_buffer_size can fail on large response headers β oversized cookies are a classic trigger.
Wrong upstream address. The proxy points at a host or port that has moved, or at a container that was rescheduled and now has a different address.
Backend overwhelmed. Under heavy load a backend may refuse connections outright, which the proxy reports as 502 rather than 503.
Certificate problems on the internal hop. An expired or untrusted certificate between proxy and backend breaks the connection before any HTTP is exchanged.
3. How to Diagnose It
Identify which proxy is answering. The error page usually names it β Nginx, Cloudflare, an AWS load balancer. Cloudflare's own 502 page differs from the one it passes through from your origin, and telling them apart says whether the problem is at the edge or at your server.
Check whether the backend is running. Obvious and frequently correct. Is the process alive, is it listening, is it on the expected port?
Request the backend directly, bypassing the proxy. If a direct request succeeds and through the proxy fails, the problem is the hop between them β address, protocol, certificate, or buffers. If the direct request also fails, the backend is the problem.
Read the proxy's error log. Nginx logs the actual reason: connect() failed, upstream prematurely closed connection, upstream sent too big header. This names the cause precisely and is far more useful than the status code.
Check the backend's logs at the same timestamp. An out-of-memory kill or a worker timeout will be recorded there while the proxy only sees the consequence.
Correlate with load and deploys. 502s during rollouts usually mean the proxy routed traffic to instances that were not ready β a health-check configuration issue rather than an application bug.
4. How to Fix It
If the backend is down: restart it, and then find out why it stopped. A 502 that resolves on restart and returns later is a crash loop wearing a disguise.
If workers time out: raise the worker timeout, or fix whatever is slow. Note that raising the proxy timeout alone converts a 502 into a slow response, which may not be an improvement.
If headers are too large: increase proxy_buffer_size and proxy_buffers, or reduce what you are sending. Accumulated cookies are the usual culprit.
If it is a protocol mismatch: align the schemes. proxy_pass https:// for a TLS backend, plain http:// otherwise.
If it happens during deploys: configure readiness checks so the proxy only sends traffic to instances that can serve it, and drain connections before shutting instances down.
If the backend is overwhelmed: add capacity, add rate limiting, or shed load deliberately with 503 β a controlled refusal is better than an unpredictable one.
As a client: retry with exponential backoff. A 502 is usually transient, and unlike 403 it carries no implication that you are unwelcome. Avoid blind retries of non-idempotent requests, since the backend may have processed the request before failing to respond.
5. HTTP 502 vs Related Status Codes
| Code | Emitted by | Meaning |
|---|---|---|
| 500 Internal Server Error | The application | It ran and failed |
| 502 Bad Gateway | A proxy | Upstream gave an invalid or no response |
| 503 Service Unavailable | Either | Temporarily unable to serve β often deliberate |
| 504 Gateway Timeout | A proxy | Upstream was reached but did not answer in time |
502 and 504 are close relatives and often confused. 502 means the answer was unusable; 504 means no answer arrived before the deadline. A backend that is slow produces 504; one that is broken produces 502.
6. Real-World Examples
- 502 for thirty seconds during every deploy. Traffic is routed to instances before they are ready β a readiness-probe problem, not an application one.
- 502 only for logged-in users. Session cookies push response headers past the proxy's buffer size, while anonymous requests stay under it.
- Intermittent 502 under load. Backend workers are being killed for memory, and the proxy sees the connections drop.
- 502 immediately after enabling HTTPS on the backend β the proxy is still configured to speak plain HTTP upstream.
- Cloudflare 502 with a Cloudflare-branded page points at the edge; an origin-branded page means Cloudflare relayed your own proxy's error.
7. Summary
502 Bad Gateway is a proxy reporting that the server behind it gave an unusable response. The proxy is the messenger, and the fault lies upstream β down, crashed, timed out, misconfigured, or speaking the wrong protocol.
Diagnose by bypassing the proxy and requesting the backend directly; that single test splits the problem space in half. Then read the proxy's error log, which names the actual failure far more precisely than the status code does. As a client, retry with backoff and be careful with non-idempotent requests, because a 502 does not tell you whether the work was done before the response was lost.