Every HTTP response carries a three-digit status code, and that number tells you what actually happened to your request. Defined in RFC 9110 (HTTP Semantics), these codes fall into five classes, and knowing which class you’re in is usually half the diagnosis.
The five-class structure
The first digit of a status code defines its class. Once you internalize that, you can read any unfamiliar code:
- 1xx — Informational: the request was received and processing continues (rarely seen in normal web work;
100 Continueand103 Early Hintsare the main ones). - 2xx — Successful: the request was received, understood, and accepted.
- 3xx — Redirection: further action is needed to complete the request — typically following a new URL.
- 4xx — Client error: the request is malformed or unauthorized. The client did something wrong.
- 5xx — Server error: the server failed to fulfill an apparently valid request. The server is the problem.
If you want to look up an unfamiliar code quickly, the IANA HTTP Status Code Registry is the canonical list.
The 2xx family: success has flavors
200 OK— the default success. GET returned the resource, POST processed the body.201 Created— the right response when your POST created a new resource. It should point to the new resource via theLocationheader.204 No Content— success, but there is no body to return. Common for PUT/PATCH/DELETE that update state without returning a representation.
A common bug: returning 200 from a create endpoint instead of 201. Clients that rely on the status to decide whether to navigate to the new resource will misbehave.
3xx: redirects and their cache traps
301 Moved Permanently— browsers and search engines cache this aggressively. Once a URL 301s, repeat visits skip the original URL entirely. Great for permanent migrations; a problem if you change your mind.302 Found— a temporary redirect. Search engines keep the original URL indexed. Use this for short-term routing.304 Not Modified— returned in response to a conditional request (withIf-Modified-SinceorIf-None-Match). The browser uses its cached copy. This is the status that makes the web feel fast.
The 301-vs-302 distinction matters for SEO: an entire site’s ranking can shift onto the new URL after a 301, while a 302 preserves the original.
4xx: the client did something wrong
401 Unauthorized vs 403 Forbidden is the distinction developers trip over most. The names are misleading, so go by the meaning in RFC 9110:
401 Unauthorizedactually means unauthenticated. You sent no credentials, or the credentials were invalid. The fix is on the user’s side: log in. RFC 9110 requires aWWW-Authenticateheader.403 Forbiddenmeans the server knows who you are, but you are not allowed to do this. Logging in again won’t help. The fix is server-side: change the permission.
Quick test: if your browser is logged in and you still get 403, it’s a permissions problem, not an auth problem.
404 Not Found vs 410 Gone: both mean the resource isn’t there, but 410 Gone is explicit — it existed once and was deliberately removed. Search engines treat 410 as a stronger signal to drop the URL from the index faster than a 404.
429 Too Many Requests — rate limiting. The response should include a Retry-After header telling you how long to wait. When you see 429, do not retry immediately; back off exponentially or your next requests get throttled harder.
5xx: the server-error family
Each 5xx code points at a different layer of the server stack, and knowing which one narrows the diagnosis fast.
500 Internal Server Error— something blew up inside the application. Check the logs for an unhandled exception.502 Bad Gateway— a proxy or load balancer got an invalid response from the upstream server. The classic symptom: your CDN or reverse proxy reached for the backend, and the backend returned garbage or nothing. Check whether the backend is up.503 Service Unavailable— the server is temporarily unable to handle the request, usually because it’s overloaded or down for maintenance. Often returned by a load balancer when no healthy backend is available. If a/healthendpoint returns503, your orchestrator is about to recycle the instance.504 Gateway Timeout— the proxy waited for the upstream and gave up. The backend is either slow or hung. When you see504, check the upstream’s response time and whether it’s saturating a connection pool.
The mental model: 500 is a crash, 502 is a broken response, 503 is a refused or overloaded server, 504 is a server that never answered in time.
When you see X, check Y
- See
401? Check whether the auth token is present and valid. - See
403? Check the user’s role and permissions. - See
429? Check your rate-limit headers and back off. - See
502? Check whether the upstream service is healthy. - See
503? Check server load and whether a deployment is mid-flight. - See
504? Check upstream latency and timeouts.
Status codes are diagnostic breadcrumbs, and reading them precisely saves hours of guessing. If you want to decode a code without reaching for a search engine every time, keep an HTTP status code reference open while you debug — it lists every registered code with its meaning, common causes, and the header that usually accompanies it.