The five classes of HTTP status codes
The first digit of a status code tells you its class:
| Class | Meaning | Most common |
|---|---|---|
| 1xx Informational | The request was received and processing continues. | 100 , 101 , 103 |
| 2xx Success | The request was received, understood and accepted. | 200 , 201 , 204 , 206 |
| 3xx Redirection | The client must take further action, usually following a redirect. | 301 , 302 , 304 , 308 |
| 4xx Client error | The request contains an error or can’t be fulfilled. Retrying unchanged won’t help. | 400 , 401 , 403 , 404 |
| 5xx Server error | The server failed to fulfil a valid request. The problem is on the server side. | 500 , 502 , 503 , 504 |
A client that receives a code it doesn’t recognise treats it as the first code of that class: an unknown 4xx is handled like 400, an unknown 5xx like 500. That is why picking the right class matters more than the exact number.
Choosing the right status code for an API
- Created something? 201 with a
Locationheader. Started a background job? 202. - Nothing to return? 204, for example after a DELETE.
- Bad input? 400 if it can’t be parsed, 422 if it fails validation, 409 if it conflicts with existing data.
- Not logged in? 401. Logged in but not allowed? 403.
- Too many requests? 429 with
Retry-After. - Your bug? 500. Down for maintenance? 503 with
Retry-After.
Never return 200 OK with an error message in the body. Caches, retries, monitoring and client
libraries all decide what to do from the status code.
Proxy and CDN errors
Some codes in the list aren’t in any standard. 499 and 444 appear only in nginx logs, and Cloudflare uses 520 to 526 to say what went wrong between Cloudflare and your origin server. They are included because they are among the codes developers search for most when debugging.
Frequently asked questions
What is the difference between 401 and 403?
401 Unauthorized means the server doesn’t know who you are: credentials are missing, expired or invalid, and logging in may fix it. 403 Forbidden means the server knows who you are (or doesn’t care) and won’t allow the request; logging in again won’t help.
Should I use 400 or 422 for validation errors?
Use 400 Bad Request when the request can’t be parsed at all, such as malformed JSON or a wrong content type. Use 422 Unprocessable Content when the request is well-formed but the data fails validation, such as an invalid email address. FastAPI, Rails and Laravel return 422 for validation errors by default.
What is the difference between 502 and 504?
Both come from a proxy or gateway in front of your app. 502 Bad Gateway means the backend gave an invalid response or refused the connection. 504 Gateway Timeout means the backend didn’t respond in time.
Which redirect should I use: 301, 302, 307 or 308?
For permanent moves use 301 (or 308 if the request method and body must be kept, e.g. for API POST requests). For temporary redirects use 302 (or 307 to keep the method). After a form POST, redirect with 303 so the result page is loaded with GET.
Can I make up my own HTTP status codes?
You shouldn’t. Clients treat unknown codes as the x00 code of their class, so a made-up 499 is handled like 400. Use the closest standard code and put details in the response body, for example in RFC 9457 problem details format.