Guide
What causes a 502 bad gateway (and what to do)
“Bad Gateway” decoded — which of your two servers is actually broken, and how to get it answering again.
Published · Updated
A 502 Bad Gateway means the server your browser reached — a proxy like nginx or Apache, or a CDN like Cloudflare — asked the real application behind it for the page and got a broken answer, or none at all. The middleman is fine; the thing behind it isn't. That makes 502 different from a 500, where the application answered but crashed while doing so. The usual causes: the app process is down or restarting, it took too long to respond, a deploy left the proxy pointing at nothing, or every worker is busy. First move: check whether your application process is actually running.
The two-server picture
Almost no website hands your browser a page directly from the application anymore. There is a front server — nginx, Apache, a load balancer, or a CDN — that accepts the request and passes it to the application behind it (the “upstream”). A 502 is the front server saying: “I'm here, I asked, and what came back wasn't a usable answer.” Maybe the connection was refused, maybe it was cut off mid-reply, maybe the response was garbage.
This is useful information. It tells you the outage is not in DNS, not in your certificate, and not in the front server — it is in the hop between the proxy and your application.
502 vs 500 vs 503
- 500 — the application answered, but it crashed while building the page. The app is up; the code failed. See what causes a 500 error.
- 502 — the application gave the proxy a broken answer or none at all. Often the app isn't really running.
- 503 — the server is up but deliberately or temporarily refusing work: overload, maintenance, rate limiting. See what causes a 503 error.
The usual causes
- The app process is down. It crashed, ran out of memory and was killed, or never came back after a restart — nginx or your CDN is knocking on a door with nobody behind it. In practice this is the most common cause.
- The upstream died mid-reply. The app hit its own timeout — a slow database query on an overloaded server — and its worker was killed mid-response, so the proxy got a cut-off answer. (A proxy that gives up waiting on its own reports a 504 instead.)
- A bad deploy. The new version failed to boot, or the proxy config points at a port or socket the new version doesn't listen on. Everything looked green in the deploy log; the app just isn't where the proxy expects it.
- Exhausted workers. Every PHP-FPM, Gunicorn or Node worker is busy or wedged, so new connections get refused. The app is “running” but effectively deaf.
Fixes, in order of likelihood
- Check whether the application process is running — and restart it if it isn't. A large share of 502s end right here, with one restart command or one click in a hosting dashboard.
- Read the app's logs around the moment it stopped. If the process keeps dying, the logs say why: an out-of-memory kill, an unhandled crash on boot, a missing environment variable after a deploy.
- Roll back the last deploy if the 502s started right after one. Restore service first, debug the new version calmly afterwards.
- Check the proxy's error log. nginx and Apache record exactly what went wrong upstream — “connection refused” means nothing is listening; “upstream timed out” means it is listening but too slow.
- Look at worker counts and timeouts if 502s come in bursts under load: more workers, longer proxy timeouts, or the slow code path fixed.
Your host or your app?
If you run the server, the checklist above is yours. On managed hosting or behind a CDN, the split is: a 502 branded by your CDN (a Cloudflare error page, for example) almost always means the CDN could not get a good answer from your origin server — check the error page's connection diagram and the CDN's status page to confirm which hop failed before assuming it is on your side. A plain, unbranded 502 from shared hosting is often the host's stack itself, and worth a support ticket. When you open one, include the exact time, the URL, and the status code — our guide on what to send your hosting provider has copy-paste templates that get faster answers.
Catching 502s before your visitors do
502s love the worst hours: the overnight deploy, the traffic spike, the memory leak that finally tips over on Sunday. Because the front server still answers, the site can even look “up” to a naive ping while serving errors to every visitor. A monitor that reads the actual HTTP status catches the 502 on the next check and tells you in plain English that your application — not your domain, not your certificate — stopped answering. You can see the status code and redirect chain your URL returns right now with the free HTTP status check.