Explained
Your site is showing 502 Bad Gateway — what that actually means
Real server problems, translated into plain English by Onserva.
What you're seeing
Your domain loads, but instead of your site there is a spare, unstyled page reading “502 Bad Gateway”. It looks nothing like anything you built, which is the first clue: that page did not come from your application. Refreshing sometimes helps and sometimes doesn't. The response arrives instantly, which somehow makes it worse — something out there is clearly alive, and it is choosing to tell your customers no.
What it actually means
Between the internet and your application sits a reverse proxy — Traefik on a Coolify box, otherwise usually nginx or Caddy. Every request arrives at the proxy first, and the proxy passes it inward to whichever app should answer it.
A 502 is the proxy saying: I tried to hand this request to your application, and I did not get a usable answer back. It is a message about the conversation behind the front door, written by the doorman.
Two things follow from that, and both are better news than they feel. The proxy is working perfectly — it took the request, tried to route it, and reported honestly when it couldn't. And the machine itself is very likely fine: it has power, network, and enough health to compose you an error page in milliseconds. “The server is down” is the natural conclusion and it is usually wrong. Something narrower is broken, one layer in.
The three usual causes
In rough order of how often they turn out to be the answer:
- 1. The app isn't running. It crashed, it was shut down by the system for using too much memory, or it is stuck in a restart loop — starting, failing, starting again. The proxy keeps knocking on a door with nobody behind it. This is the most common cause by some distance, and an out-of-memory kill is the most common reason for it.
- 2. The app is running, but not where the proxy is looking. It came up on a different port than the proxy expects, or bound only to “localhost” inside its own container, where nothing else can reach it. Everything looks healthy from the app's side — its logs are clean, it reports itself ready — and the proxy still finds nothing. This one almost always appears immediately after a deploy or a configuration change, which is the tell.
- 3. The app is answering too slowly to count. The proxy will only wait so long. An application labouring under load, stuck behind a slow database query, or thrashing because the machine is short of memory can take longer to reply than the proxy is willing to give it. The connection is abandoned, and the visitor gets a 502. This is the version that comes and goes with traffic, which makes it the hardest to catch by refreshing.
What to do now
- Ask whether the app is actually running. On Coolify, look at the application's status: a container that has stopped, or that is cycling through restarts, answers the question immediately. Cause one is so much more common than the others that it is worth ruling out before thinking about anything else.
- If it is restarting, look at memory before logs. An app killed for memory often leaves no useful error of its own — it is stopped from outside, mid-sentence. What memory was doing on the machine around the time it died tells you more than the application's own last words.
- If the 502 started right after a change, suspect the change. A deploy, a new environment variable, an edited port. Cause two hides here. Compare the port the app is listening on against the one the proxy is configured to reach.
- If it comes and goes, watch it under load. Intermittent 502s are cause three until proven otherwise. Look at how long the successful requests are taking — if the slow ones get slower as traffic rises, the proxy is timing out on a queue, not on a dead app.
- Only then read the application's logs. They are genuinely useful for a crash with a cause, and quietly misleading for the other two: an app that never received the request has nothing to say about it.
When to worry
A total 502 — every request, all the time — is alarming and rarely serious. It is loud, obvious, and someone fixes it within the hour, because it is impossible to ignore.
The version worth taking seriously is the intermittent one: a few percent of requests failing, mostly at busy times. Nobody notices it from a browser, because refreshing works. It does not wake anyone. And it is quietly turning away a slice of every day's customers — the ones who assume your site is broken and go elsewhere without ever telling you. A site failing one request in twenty looks perfectly healthy to its owner and quite broken to the public.
The other pattern to respect is a 502 that keeps coming back after a restart cures it. A restart that works is not a diagnosis; it is a reset of whatever was accumulating. If the same failure returns on a schedule — every few days, every Monday morning — something is leaking, and the interval is itself a clue about what.
How Onserva handles this
Onserva reads your reverse proxy's own access log, on the machine, and counts what it is actually returning — so failed requests are a number rather than a hunch. It knows what share of requests are failing and tells you when that share climbs, including the intermittent case that never looks broken in a browser. It watches per-container memory alongside it, so a 502 caused by an app being killed for memory arrives with the reason attached instead of as a mystery. And because it also checks your sites from outside the machine, the way a visitor reaches them, it can tell you that customers are seeing an error page even when the server looks perfectly healthy from the inside.