HTTP Status Codes Explained

Every HTTP response carries a three-digit status code that tells the client, in a standard and machine-readable way, what happened with its request. The first digit places the code into one of five classes, from informational through success, redirection, client error, and server error, so even an unfamiliar code can be roughly understood at a glance. Using the correct code matters because clients, proxies, and caches all change their behaviour based on it — retrying, following redirects, or surfacing an error. This guide covers the five classes and the individual codes you will encounter most often, along with the reasoning for choosing one over another.

  1. 1. The five classes

    The leading digit defines the class: `1xx` is informational (the request was received and processing continues), `2xx` is success (the request was understood and fulfilled), and `3xx` is redirection (further action, usually following a new URL, is needed). `4xx` is a client error (the request was malformed, unauthorised, or otherwise the caller’s fault), while `5xx` is a server error (the request was valid but the server failed to handle it). Knowing only the class already tells you whether a request succeeded, needs redirecting, or failed — and on whose side the fault lies.

  2. 2. Success codes (2xx)

    `200 OK` is the general success response, returned for a normal `GET` or any request that succeeded and has a body to return. `201 Created` is the right answer to a request that created a new resource, typically a `POST`, and usually includes a `Location` header pointing to the new resource. `204 No Content` signals success with deliberately no response body, which suits a `DELETE` or an update where the client needs no data back. Choosing `201` and `204` over a blanket `200` makes the outcome of write operations precise and self-describing.

  3. 3. Redirection codes (3xx)

    `301 Moved Permanently` tells clients and search engines the resource has a new permanent URL, so they should update their links; it is heavily cached. `302 Found` is a temporary redirect, indicating the resource lives elsewhere for now but the original URL should still be used in future. `304 Not Modified` is a special case used for caching: it carries no body and tells the client its cached copy is still valid, saving the cost of resending unchanged data. The permanent-versus-temporary distinction matters because a wrongly cached `301` is hard to undo.

  4. 4. Common client errors (4xx)

    `400 Bad Request` means the request was malformed or otherwise unprocessable at a basic level. `401 Unauthorized` means authentication is missing or invalid (you are not logged in), whereas `403 Forbidden` means you are authenticated but not allowed to do this — the two are frequently confused. `404 Not Found` means the resource does not exist, and `409 Conflict` signals a clash with the current state, such as a duplicate or a version mismatch. `422 Unprocessable Entity` indicates the syntax was fine but the data failed validation, and `429 Too Many Requests` tells a client it has been rate-limited and should slow down.

  5. 5. Server errors (5xx)

    The `5xx` range means the request was acceptable but the server failed to fulfil it, so the fault lies with the server rather than the caller. `500 Internal Server Error` is the generic catch-all for an unhandled exception or bug. `502 Bad Gateway` means a server acting as a proxy or gateway received an invalid response from an upstream server, while `503 Service Unavailable` means the server is temporarily unable to handle the request, often due to overload or maintenance, and may include a `Retry-After` header. Because these are not the client’s fault, well-behaved clients may retry `5xx` responses, ideally with backoff.

  6. 6. Idempotency and choosing the right code

    Idempotency — whether repeating a request has the same effect as making it once — guides both retries and which code to return. Safe, idempotent methods like `GET`, `PUT`, and `DELETE` can be retried by clients and proxies after a network failure, which is partly why a `5xx` server error is safer to retry than a `4xx`, where retrying the same bad request will simply fail again. Return codes that match the real outcome: `201` when something was created, `409` for a conflicting state, `422` for failed validation rather than a vague `400`, and `429` rather than silently dropping abusive traffic. Accurate status codes let clients react correctly without parsing the response body to discover what happened.

← All developer guides