What HTTP status codes are
Your checkout page worked fine all morning. Now it shows a blank screen, and the network tab says 422. Was that the browser, your code or the payment API? The status code is the first clue, and it tells you more than you might think.
Every HTTP response starts with a three-digit code saying how the request went. The first digit gives you the class, so you know the rough story before you look up the exact number:
- 1xx: informational, the request is still in progress
- 2xx: success
- 3xx: redirection, the client has to do something else
- 4xx: client error, the request itself is wrong
- 5xx: server error, the request looked fine but the server failed
A handy rule of thumb: 4xx means “you broke it”, 5xx means “they broke it”. The code sits in the status line, the very first line of the response, before the headers:
HTTP/1.1 404 Not Found
Content-Type: application/json
{"error": "Order ord_7Q2K for Priya Nair not found"}The codes and their meanings are defined in RFC 9110, with a few extras such as 429 (RFC 6585) and 103 (RFC 8297).
1xx informational
Think of a 1xx as the server saying “got it, hang on”. It’s an interim response, and the real one follows on the same connection. Your HTTP client usually deals with these quietly, so you’ll rarely see one in your own code.
| Code | Name | Meaning |
|---|---|---|
| 100 | Continue | The server has the request headers and the client can send the body. Sent in reply to Expect: 100-continue. |
| 101 | Switching Protocols | The server agrees to an Upgrade request, for example from HTTP/1.1 to WebSocket. |
| 103 | Early Hints | Sends Link headers ahead of the final response so the browser can start preloading resources. |
2xx success
The happy path. The server got your request, understood it and did what you asked. The exact code tells you a bit more, like whether something new was created or whether there’s a body to read at all.
| Code | Name | Meaning |
|---|---|---|
| 200 | OK | The request succeeded. For a GET, the body holds the requested resource. The most common code. |
| 201 | Created | A new resource was created, usually by a POST or PUT. The Location header often points to it. |
| 202 | Accepted | The request was accepted for processing, but processing has not finished. Common for background jobs. |
| 204 | No Content | The request succeeded and there is no body. Common for DELETE and for updates that return nothing. |
| 206 | Partial Content | Only part of the resource is returned, as asked for by a Range header. Used for resumable downloads and video seeking. |
3xx redirection
The thing you asked for is somewhere else, and the Location header tells you where. It’s like a forwarding address after a move. The redirect codes differ in two ways: is the move permanent, and may the client change the request method when it follows the redirect? That second question is the one people forget.
| Code | Name | Meaning |
|---|---|---|
| 301 | Moved Permanently | The resource has a new permanent URL. Search engines move ranking to it. Clients may turn a POST into a GET when they follow it. |
| 302 | Found | The resource is temporarily at another URL. Keep using the original one. Like 301, clients may turn a POST into a GET. |
| 303 | See Other | Fetch the result from another URL with GET. The usual reply after a form POST, so a page refresh does not resubmit it. |
| 304 | Not Modified | Reply to a conditional request (If-None-Match or If-Modified-Since). The resource has not changed, so the client uses its cached copy. |
| 307 | Temporary Redirect | Like 302, but the client must repeat the same method and body. A POST stays a POST. |
| 308 | Permanent Redirect | Like 301, but the client must repeat the same method and body. |
4xx client errors
The server looked at your request and said no, because something about it is wrong. Sending it again unchanged will get the same answer, so don’t just hit retry. (429 is the exception: wait a bit and it will go through.) If you’re building against an API, you’ll see these more than any other class.
| Code | Name | Meaning |
|---|---|---|
| 400 | Bad Request | The request is malformed: invalid JSON, a missing required field, a wrong data type. |
| 401 | Unauthorized | No valid credentials. Despite the name, this is about authentication. Send a valid token or API key, usually in the Authorization header. |
| 403 | Forbidden | The server knows who you are, or does not need to, and refuses anyway. Different credentials or permissions are needed. |
| 404 | Not Found | Nothing exists at this URL. Check the path and the resource ID. Some APIs also return 404 to hide resources you may not see. |
| 405 | Method Not Allowed | The URL exists but does not accept this method, such as a DELETE on a read-only resource. The Allow header lists the methods it does accept. |
| 408 | Request Timeout | The server gave up waiting for the client to finish sending the request. |
| 409 | Conflict | The request clashes with the current state of the resource, such as a duplicate username or an edit to an outdated version. |
| 410 | Gone | The resource was removed on purpose and will not come back. |
| 413 | Content Too Large | The request body is bigger than the server accepts. Called Payload Too Large before RFC 9110. |
| 415 | Unsupported Media Type | The server does not accept the body’s format. Often a missing or wrong Content-Type header. |
| 422 | Unprocessable Content | The body is well-formed but fails validation, such as an invalid email address. Called Unprocessable Entity before RFC 9110. |
| 429 | Too Many Requests | You hit a rate limit. Slow down and retry later. If the response has a Retry-After header, wait that long. |
5xx server errors
Your request was probably fine. The server tripped over its own feet: a bug, an outage or too much traffic at once. 502, 503 and 504 often clear up on their own, so retrying after a short delay is reasonable. A 500 that happens every time is a bug, and waiting won’t fix it.
| Code | Name | Meaning |
|---|---|---|
| 500 | Internal Server Error | A generic failure: the server hit an unexpected condition. The details are in the server logs. |
| 501 | Not Implemented | The server does not support the functionality needed, for example a method it does not recognise. |
| 502 | Bad Gateway | A proxy or gateway got an invalid response from the upstream server behind it. |
| 503 | Service Unavailable | The server is temporarily unable to handle requests, usually because of maintenance or overload. May include Retry-After. |
| 504 | Gateway Timeout | A proxy or gateway did not get a response from the upstream server in time. |
Debugging an unexpected status code
Before you start guessing, read the response body. Most APIs put a plain-English error message there, and it often names the exact field that’s wrong. To see the status line, headers and body in one go, run the request with curl -i:
curl -i https://api.example.com/orders/ord_7Q2K \
-H "Authorization: Bearer $TOKEN"Then narrow it down by code:
- 400 or 422: compare your body with the API’s schema and check the
Content-Typeheader. - 401: check that the token is present, correctly formatted and not expired.
- 403: the credentials work but lack permission for this resource or action.
- 404: check the URL, the API version in the path and the resource ID.
- 429, 502, 503, 504: retry with exponential backoff and respect
Retry-After. - 500: check the server logs, or report it to the API provider with the request details.
