# HTTP Status Codes

> HTTP status codes list: what each of the 46 common codes means and when to use it, 1xx to 5xx, with 404, 410, 418, 422 and 429. 401 vs 403 explained. Free.

Source: https://www.revquix.com/tools/http-status-codes
Cost: free, no signup

---

HTTP status codes are the three-digit numbers a server returns to say what happened to a request: 1xx informational, 2xx success, 3xx redirection, 4xx client error and 5xx server error. This list covers the 46 codes you will actually meet, each with what it means and when to use it, including 401 vs 403 and 400 vs 422. Free, and nothing you search leaves your browser.

## At a glance

- Takes: A code, or a search for what you are trying to say
- Returns: What it means, when to use it, and what to send instead
- Handles: The pairs people get wrong - 401 against 403, 400 against 422, 301 against 307
- Privacy: A static reference - no request is made when you search

## 401 is not authorisation

The specification names 401 Unauthorized and means unauthenticated: we do not know who you are, so send credentials - which is why it must carry a WWW-Authenticate header. 403 Forbidden means the opposite situation: we know exactly who you are and you still may not do this, so re-authenticating will not help and sending the user to a login page is the wrong response.

Getting this backwards produces a specific, common bug: a client that redirects to login on a 403 puts a legitimately-authenticated user into an endless loop, because signing in again changes nothing. There is one deliberate exception worth knowing - where confirming that a resource exists would itself leak information, returning 404 to an unauthorised caller is the right answer rather than 403.

## 400 or 422

400 Bad Request means the request could not be read: unparseable JSON, a missing required field, a value of the wrong type. 422 Unprocessable Content means it was read perfectly and is still wrong - a well-formed email address that is already taken, an end date before its start date, a quantity larger than the stock.

The distinction is worth maintaining because it tells the client whether to fix its serialisation or to show the user a field error, and those are entirely different code paths.

## The three redirects that are really six

302 is historically ambiguous: the specification says preserve the request method, every browser changes POST to GET. That ambiguity is why 303 and 307 exist - 303 See Other explicitly means redirect with GET, and 307 explicitly means keep the method. 308 is the permanent, method-preserving counterpart to 301.

For new work, prefer the explicit pair: 303 after a successful form POST so a refresh does not resubmit, and 307 or 308 whenever a POST must stay a POST. 301 remains the one that reliably passes search authority, and browsers cache it hard enough that a mistaken 301 is close to irreversible for returning visitors.

- Search by number - typing 40 lists the whole 40x range
- Or by symptom, including phrases like rate limit and forbidden vs unauthorized
- Codes cacheable by default under RFC 9111 are marked
- Codes registered with IANA but absent from a core RFC are labelled as such

## What it will not do

It will not tell you which code your framework is actually returning, and that gap matters: a proxy, a CDN or an error handler in the middle can and does rewrite a status on the way out. Check the response over the wire rather than the code your handler thinks it set.

It is also not exhaustive. 46 codes are covered - the ones you will actually meet - and the WebDAV and unofficial extensions are included only where they are widely deployed or widely looked up. Inventing a status code for your own API is a non-goal for the same reason: clients and proxies only understand the registered ones.

## Questions people ask

### What is the difference between 401 and 403?

401 means unauthenticated - we do not know who you are, so send credentials, and the response must include a WWW-Authenticate header. 403 means authenticated but not permitted, so re-authenticating will not help. Redirecting to login on a 403 creates a loop for a user who is already signed in.

### Should a validation error be 400 or 422?

422 if the request was well-formed and the content is wrong - a duplicate email, an end date before its start. 400 if the request itself could not be read, such as malformed JSON or a missing required parameter. The distinction tells the client whether to fix its serialisation or to display a field error.

### Which redirect preserves the HTTP method?

307 for a temporary redirect and 308 for a permanent one. 301 and 302 historically rewrite POST to GET despite what the specification says, and 303 does so deliberately. Use 303 after a form submission so a refresh does not resubmit, and 307 or 308 whenever a POST must remain a POST.

### What does 429 Too Many Requests mean?

The client sent too many requests in a given period: it is the rate-limiting code (RFC 6585). Send a Retry-After header with it. Without one, a well-behaved client has to guess when to try again, and the usual guess is immediately, which is exactly the traffic the limit was meant to stop.

### What is the difference between 502, 503 and 504?

502 Bad Gateway: a proxy got an invalid response from the server behind it, often because the application is not listening where the proxy expects. 503 Service Unavailable: the server is deliberately or temporarily unable to cope, as in maintenance or overload, and should send Retry-After. 504 Gateway Timeout: the proxy gave up waiting, and the request may still have succeeded upstream.

### Which status code means a resource already exists?

409 Conflict, for a duplicate that breaks a uniqueness rule or an edit that lost an optimistic-concurrency race. Put what conflicted in the body, because 409 alone leaves the client with no next step. If the payload is well-formed but fails a business rule rather than colliding with existing state, 422 is the better fit.

### Is an empty result a 404?

No. A successful query that matched nothing is 200 with an empty list - the endpoint exists and answered. 404 means the resource or route itself does not exist. Returning 404 for an empty collection forces every client to treat a normal outcome as an error.

### Can I invent my own status code?

You can, and you should not. Clients, proxies and CDNs only reason about registered codes, and an unknown one is treated as the generic case for its class - so a made-up 499 behaves as an unspecified 4xx and communicates nothing. Put the detail in the response body instead.
