Quick answer
HTTP 502 Bad Gateway means a server acting as a gateway or proxy received an invalid response from the upstream server it was trying to reach.
What HTTP 502 means
502 Bad Gateway happens at the proxy layer. A reverse proxy or load balancer (nginx, a CDN, an API gateway) forwarded your request to an upstream server, but got back something invalid — or nothing usable. The proxy itself is fine; the upstream is the problem.
Common causes
- The upstream server is down or crashed
- The upstream returned a malformed response
- A reverse proxy is misconfigured (wrong upstream address/port)
- The upstream timed out or reset the connection
Example JSON error response
{
"error": "Bad Gateway",
"message": "The upstream server returned an invalid response.",
"status": 502
}
Raw HTTP response
HTTP/1.1 502 Bad Gateway
Content-Type: application/json
How to troubleshoot HTTP 502
- ✓ Check the upstream/origin server is running and healthy
- ✓ Verify the reverse proxy points at the correct upstream address and port
- ✓ Inspect upstream logs for crashes or malformed responses
- ✓ Check upstream timeout and keep-alive settings
- ✓ Confirm the upstream is not being restarted or redeployed
502 vs 503 vs 504 — what's the difference?
502 Bad Gateway: the proxy got an invalid response from the upstream. 503 Service Unavailable: the server is up but temporarily can't handle the request (overload/maintenance). 504 Gateway Timeout: the upstream didn't respond in time. 502 = bad response, 503 = not available, 504 = too slow.
Why a 502 is usually not your client's fault
A 502 almost always means the request never reached a healthy application — it died at the proxy/upstream boundary. That's why a 502 often has an HTML body from nginx or the CDN rather than your API's JSON: your app never got to format a response. If you're calling an API and see a 502, the fix is rarely in your request; it's a transient upstream problem, so retry with backoff:
const res = await fetch('/api/data');
// 502 is typically transient (upstream restarting/redeploying)
if (res.status === 502 || res.status === 503 || res.status === 504) {
return retryWithBackoff(() => fetch('/api/data'), { max: 3 });
}
// don't assume JSON on a 502 — proxies often return an HTML error page
const type = res.headers.get('Content-Type') || '';
const body = type.includes('application/json') ? await res.json() : await res.text();
Common 502 causes if you run the server
| Layer | Typical cause |
|---|---|
| Upstream app | Crashed, out of memory, or still booting after a deploy |
| Proxy config (nginx) | proxy_pass pointing at the wrong host/port |
| Connection | Upstream closed the connection or returned malformed headers |
| Scaling | All backend instances unhealthy / failing health checks |
Frequently Asked Questions
What causes a 502 Bad Gateway?
A reverse proxy or gateway received an invalid or empty response from the upstream server. Usually the upstream is down, crashed, misconfigured, or returned something the proxy could not parse.
How do I fix a 502 error?
Check that the upstream/origin server is running and healthy, verify the proxy is pointing at the correct address and port, and inspect the upstream logs. Restarting a crashed upstream or fixing the proxy config usually resolves it.
What is the difference between 502 and 504?
502 Bad Gateway means the upstream returned an invalid response. 504 Gateway Timeout means the upstream did not respond at all within the time limit. Both are proxy-layer errors, but 502 is a bad reply and 504 is no reply in time.
Should I retry a 502?
Yes — a 502 is usually transient (an upstream restarting, redeploying, or briefly unhealthy), so retrying a GET with exponential backoff is appropriate. As with any 5xx, be careful retrying non-idempotent requests unless they're protected by an idempotency key.
Why is my 502 response HTML instead of JSON?
Because the error came from the proxy or CDN, not your application — your app never ran to produce a JSON body. nginx, load balancers, and CDNs emit their own HTML error pages. Don't assume a JSON body on a 502; check the Content-Type before parsing.
Working with a JSON API response?
Format and inspect any response in your browser — nothing is uploaded.