You push a deploy, refresh the page, and there it is in ugly grey letters: 502 Bad Gateway. Your stomach drops. Is it the server? The load balancer? The code? The internet itself?
Here's the good news: that number isn't random. Every HTTP status code is your server (or something between you and it) trying to tell you exactly what went wrong — if you know how to read it. Learn the handful that matter and you'll diagnose problems in seconds instead of panicking.
The five families
Every status code is a three-digit number, and the first digit tells you the category. Get this and you're already halfway there:
| Range | Family | Rough meaning |
|---|---|---|
| 1xx | Informational | "Hold on, still working." (You'll rarely see these.) |
| 2xx | Success | "Here you go." Everything worked. |
| 3xx | Redirection | "It moved — look over there instead." |
| 4xx | Client error | "You sent something wrong." |
| 5xx | Server error | "I messed up." |
The single most useful distinction: 4xx is your fault, 5xx is the server's fault. A 404 means the browser asked for something that isn't there; a 500 means the server fell over trying to answer. That one rule points your debugging in the right direction immediately.
The codes you'll actually meet
You don't need all 70-odd codes. You need these.
Success and redirects
| Code | Name | What it means |
|---|---|---|
| 200 | OK | The request worked. The happy path. |
| 201 | Created | Your POST created something (common in APIs). |
| 204 | No Content | Worked, but there's nothing to send back. |
| 301 | Moved Permanently | This URL has a new home — forever. Search engines update accordingly. |
| 302 | Found (temporary redirect) | Moved for now; keep using the old URL. |
| 304 | Not Modified | "Nothing changed, use your cached copy." A speed win. |
Client errors (4xx)
| Code | Name | What it usually means | What to check |
|---|---|---|---|
| 400 | Bad Request | Malformed request the server can't parse | Your payload, syntax, params |
| 401 | Unauthorized | You're not logged in / no valid credentials | Auth token, login |
| 403 | Forbidden | You're known, but not allowed | Permissions, IP allowlists |
| 404 | Not Found | That URL doesn't exist | The path, typos, deleted pages |
| 429 | Too Many Requests | You're being rate-limited | Slow down, back off and retry |
Server errors (5xx)
| Code | Name | What it usually means | Likely culprit |
|---|---|---|---|
| 500 | Internal Server Error | The app crashed handling the request | A bug, an unhandled exception |
| 502 | Bad Gateway | A proxy got a junk response from upstream | App down behind the load balancer |
| 503 | Service Unavailable | Server is up but can't serve right now | Overload, or maintenance mode |
| 504 | Gateway Timeout | Upstream took too long to respond | A slow app, DB or dependency |
The 5xx trio that causes the most panic
500, 502, 503 and 504 look similar but tell very different stories:
- 500 — your application itself threw an error. Check your logs; there's almost always a stack trace.
- 502 — something in front of your app (a proxy, load balancer, CDN) tried to reach it and got nothing usable. Usually your app crashed or isn't listening.
- 503 — the server is alive and answering, but deliberately saying "not now" — often overload or a maintenance page.
- 504 — the front layer waited for your app and gave up. Your app (or a database/third-party it calls) is too slow.
A quick mental shortcut: 502 = "the thing behind me is dead", 504 = "the thing behind me is slow". That distinction alone saves a lot of wrong turns.
Why this matters for monitoring
Status codes are the backbone of uptime monitoring. When a monitor checks your site, the code is the first thing it reads:
- A 2xx is treated as healthy.
- A 4xx or 5xx can be treated as down — though a good setup lets you decide (a 401 on a protected endpoint might be expected).
- Sudden 5xx spikes are the classic signal of a real outage.
But there's a trap: a page can return 200 OK and still be broken — a blank page, an error rendered in the body, the wrong content entirely. That's why solid monitoring pairs the status code with a keyword (body) check, so "200 but broken" still counts as down.
The bottom line
| If you remember one thing… | …make it this |
|---|---|
| First digit | tells you the family: 2 good, 3 moved, 4 your fault, 5 server's fault. |
| 4xx vs 5xx | points your debugging in the right direction instantly. |
| 502 vs 504 | "dead upstream" vs "slow upstream". |
| 200 isn't enough | pair status checks with a content check to catch "200 but broken". |
Status codes feel cryptic until they don't. Once these click, that grey 502 stops being a mystery and starts being a map.
Want something watching your status codes around the clock? Our HTTP monitoring guide shows how to alert on the right ones — and you can inspect any URL's response right now with the free HTTP header checker.