HTTP Status Codes, Explained
After reading this you will be able to read any HTTP status code, know which of the five classes it belongs to, predict what a well-behaved client should do about it, and avoid the handful of mistakes that break caches, redirects and error handling.
Every HTTP response starts with a status line. A server that answers a request for a page sends something like HTTP/1.1 200 OK. The three-digit number is the status code, and the words after it are the reason phrase. The number is what machines act on. The reason phrase is only for humans, and RFC 9110 says clients should ignore it (Section 15).
Here is the hook. A browser asks for /report, the server answers 301 Moved Permanently with a Location: /reports/2024 header. The browser does not show an error. It quietly fetches the new URL, and next time it may skip the old address entirely because 301 means the move is permanent and cacheable. Change that one digit to 302 and the browser stops caching the redirect. That single digit is the difference between a URL that disappears from history and one that keeps working. This is why the codes are worth learning precisely.
The five classes and what they promise
Every status code is a three-digit number from 100 to 599. The first digit sets the class, and the class alone tells you how to react even if you have never seen the specific code.
- 1xx informational
- The request was received and processing continues. The response is provisional. Example:
100 Continue. - 2xx success
- The request was received, understood and accepted. Example:
200 OK,201 Created,204 No Content. - 3xx redirection
- Further action is needed to complete the request, usually following a
Locationheader. Example:301,302,304 Not Modified. - 4xx client error
- The request was malformed or not allowed. The client should not repeat it unchanged. Example:
400,401,404. - 5xx server error
- The server failed to fulfil an apparently valid request. Retrying later may work. Example:
500,502,503.
RFC 9110 Section 15 states the key rule: a client that does not recognize a status code must treat it as the x00 code of its class. So an unknown 499 is handled like 400, and an unknown 522 is handled like 500. This is why the first digit matters more than the exact number.
Only these five classes exist. There is no 6xx class in HTTP. Codes like Cloudflare's 520 through 530 are non-standard extensions that still fall inside the 5xx server-error class, so clients treat them like 500.
Codes are registered, not invented
You do not get to make up a code and expect it to work. The Internet Assigned Numbers Authority (IANA) keeps the official HTTP Status Code Registry. As of the 2022 update, roughly 60 codes are registered across the five classes. That is far fewer than the 500 slots the numbering scheme allows, which leaves room for future additions.
The counts per class in the registry look roughly like this. Use them to see where the real detail lives: the 2xx, 4xx and 5xx classes carry most of the working codes.
When the code matters and when it does not
The status code is authoritative for machines. Caches key on it, browsers redirect on it, and API clients branch on it. So set it correctly on the server and read it correctly on the client.
What does not matter is the reason phrase. You can send 200 Totally Fine or 404 Nope and a compliant client behaves identically to 200 OK and 404 Not Found. HTTP/2 and HTTP/3 drop the reason phrase from the wire entirely (RFC 9113 Section 8.3.1), so any code that carries meaning in its text is already broken on modern connections.
Do not return 200 OK with an error message in the body. This is the most common API bug. A client that sees 200 treats the response as success, caches it, and never triggers its error path. If the request failed, send a 4xx or 5xx code so the machine agrees with the human.
Reading a code in three steps
You can decode any status code, including ones you have never met, with a fixed procedure. There is no formula to compute here, only a decision you repeat.
- Read the first digit to get the class. That tells you success, redirect, or which side of the wire made the mistake.
- If you recognize the exact code, use its specific meaning. If you do not, fall back to the
x00behavior for the class, exactly as RFC 9110 requires. - Check the headers the code depends on. A 3xx needs
Location. A401needsWWW-Authenticate. A405needsAllow. A503may carryRetry-After.
Worked example: the classic teapot and its neighbors
Load the tool with its defaults and search the reference. Work through four codes the same way each time.
418 I'm a teapot: first digit 4, so client error. Defined by RFC 2324 as an April Fools joke, it means the server refuses to brew coffee because it is a teapot. Some real servers send it to reject bots. A client should treat it like400and not retry unchanged.301 Moved Permanently: first digit 3, redirection. Follow theLocationheader. Cache the redirect and update stored links, because the move is permanent.429 Too Many Requests: first digit 4, client error. You sent too many requests in a window. ReadRetry-Afterand wait that many seconds before trying again.511 Network Authentication Required: first digit 5, server error. A captive portal wants you to log in before it grants network access. Defined in RFC 6585.
Notice that 418 and 429 share the leading 4, so the fallback behavior is the same even though their meanings differ. That shared class is the safety net.
The nine codes you will actually meet
A handful of codes cover the vast majority of real traffic. Learn these nine and you can read most logs on sight.
| Code | Meaning | Class | What the client does |
|---|---|---|---|
| 200 | OK | 2xx | Use the body as the result |
| 201 | Created | 2xx | Read the new resource from Location |
| 301 | Moved Permanently | 3xx | Follow and cache the redirect |
| 304 | Not Modified | 3xx | Reuse the cached copy |
| 400 | Bad Request | 4xx | Fix the request, do not retry as is |
| 401 | Unauthorized | 4xx | Authenticate, then retry |
| 404 | Not Found | 4xx | Stop; the resource is absent |
| 500 | Internal Server Error | 5xx | Retry with backoff, then report |
| 503 | Service Unavailable | 5xx | Wait for Retry-After, then retry |
Common mistakes that break real systems
These are the errors that cost hours of debugging.
- Using
302for a permanent move. Search engines and browsers may not update their stored links, so the old URL never retires. Use301for permanent,302or307for temporary. - Changing the method on redirect. Old clients turned a
POSTinto aGETafter a302. If you need the method preserved, use307 Temporary Redirector308 Permanent Redirect, which RFC 9110 defines to keep the method and body intact. - Returning
200on failure. Covered above. The machine believes you. - Confusing
401and403.401means "you are not authenticated, log in."403means "you are authenticated but not allowed." Sending401without aWWW-Authenticateheader violates RFC 9110 Section 15.5.2. - Sending a body with
204or304. Both codes forbid a message body. A body here confuses parsers and can desync the connection.
Related tools
Status codes rarely travel alone. When you inspect a response you often need to decode the surrounding parts too.
Use the URL Parser & Query Editor to split the Location header of a redirect into its parts, the MIME Type Lookup to check that the Content-Type matches the body you got with a 200, and the User-Agent Parser when a server returns 403 or 418 based on the client that asked. For front-end work on the pages behind those responses, the Color Converter & Contrast Checker, the CSS Gradient, Shadow & Radius Generator, the HTML Entity Reference and the Keycode Inspector cover the rest.
Frequently asked questions
What is the difference between 401 and 403?
401 Unauthorized means the request lacks valid authentication, so logging in may fix it, and the response must include a WWW-Authenticate header. 403 Forbidden means the server understood who you are and still refuses; logging in again will not help.
Is 418 I'm a teapot a real status code?
Yes. It is defined by RFC 2324, the Hyper Text Coffee Pot Control Protocol, as an April Fools joke in 1998. It is in the IANA registry, and some servers send it to reject automated traffic. Clients treat it like any other 4xx: a client error, do not retry unchanged.
Which redirect code should I use?
For a permanent move use 301. For a temporary one use 302. If the request method and body must survive the redirect, use 307 (temporary) or 308 (permanent), which are guaranteed not to change the method.
Should I retry a request after a 500 or a 503?
A 503 Service Unavailable often carries a Retry-After header telling you how long to wait, so retry after that delay. A 500 Internal Server Error gives no such promise; retry once or twice with exponential backoff, then report the failure. Never retry a 4xx unchanged, because the fault is on your side.
Does the reason phrase text matter?
No. Clients act on the three-digit number only, and HTTP/2 and HTTP/3 do not send the reason phrase at all. Treat the text as a comment for humans.