# HTTP Status Codes

> Every HTTP status code with its reason phrase, whether it is cacheable, whether it can carry a body, and when to use it.

Canonical: https://host-tools.com/reference/http-status-codes/

---

## What are HTTP status codes?

Every HTTP response starts with a three-digit status code that tells the client how the
request went. The first digit defines the class:

- **1xx** — informational: the server received the request and is continuing.
- **2xx** — success: the request was received and processed.
- **3xx** — redirection: the client must take an extra step, usually following a redirect.
- **4xx** — client error: the request is malformed or not allowed.
- **5xx** — server error: the server failed to fulfil an otherwise valid request.

## How to read the table

The table is grouped by class. Two of its columns come straight from the specification
rather than from opinion:

- **Cacheable** — whether a cache may reuse the response *by default*. RFC 9110 defines
exactly twelve codes as heuristically cacheable: `200`, `203`, `204`, `206`, `300`,
`301`, `308`, `404`, `405`, `410`, `414` and `501`. Every other code is only cached when
the response says so explicitly.
- **Body** — whether the response may carry a body. The whole `1xx` class cannot contain
content, `204` and `304` send no representation, and `205` must not generate content.

Use the search box to filter by code, reason phrase or description. To see which code a
live site actually returns — including every redirect — use the
[Website Status Checker](/tools/website-status/).

## Which code should you return?

The table tells you what a code means. This is the other half: what to send.

### Creating a resource

| Situation | Code |
| --- | --- |
| You created a new resource | `201 Created` — include a `Location` header |
| You accepted work to do later | `202 Accepted` |
| It worked and there is nothing to return | `204 No Content` |
| It worked and the client keeps its current view | `200 OK` |

### Redirects

| Code | Permanent? | Preserves the method? |
| --- | --- | --- |
| `301` | Yes | No — a `POST` becomes a `GET` |
| `302` | No | No — same problem, and it is the accidental default |
| `303` | No | No — that is the point: “look over there, with `GET`” |
| `307` | No | Yes |
| `308` | Yes | Yes |

Moving a `GET`-only URL permanently: `301`. Moving an endpoint where the method and body
matter: `308` if permanent, `307` if temporary. Avoid `302` for a permanent move — browsers
treat it as temporary and signals do not transfer.

### Client errors

| Code | Use it when |
| --- | --- |
| `400` | The request is malformed and authenticating would not help |
| `401` | The client is not authenticated — send `WWW-Authenticate` |
| `403` | The client is authenticated but not allowed; retrying will not help |
| `404` | The resource does not exist, or you do not want to reveal that it does |
| `405` | The method is wrong for this URL — send `Allow` |
| `409` | The request conflicts with the current state (duplicate key, stale version) |
| `422` | The body parses but fails validation |
| `429` | Rate limited — send `Retry-After` |

The pair people get wrong most often is `401` versus `403`: `401` asks “who are you?”,
`403` says “I know who you are, and no”.

### Server errors

`500` is the catch-all for a bug. When you can be precise, be precise: `502` and `504`
mean an upstream service answered badly or too slowly, and `503` means you are overloaded
or in maintenance — and only `503` lets you send `Retry-After` so clients back off
politely instead of hammering you.

## Codes that carry no body

`1xx`, `204`, `205` and `304` cannot carry a body. Sending one is a protocol error, not
just wasted bytes. `304` is the easiest to get wrong: it must not repeat the body of the
`200` it replaces, only the headers the cache needs to update.

## Sources

Reason phrases and cacheability follow the
[IANA HTTP Status Code Registry](https://www.iana.org/assignments/http-status-codes/) and
RFC 9110 (*HTTP Semantics*). Legacy codes that are no longer in use (`305 Use Proxy`,
`306 Switch Proxy`) are omitted on purpose.
