The initial part of the request was received; carry on sending the body.
Sent in response to an `Expect: 100-continue` header, so a client can avoid uploading a large body that would be rejected outright.
Every IANA-registered status code, what it means, when to send it, and the RFC that defines it.
Runs entirely in your browser — nothing you paste is uploaded.
The request was received and the process is continuing. A 1xx is a provisional response — the real one still follows.
The initial part of the request was received; carry on sending the body.
Sent in response to an `Expect: 100-continue` header, so a client can avoid uploading a large body that would be rejected outright.
The server is switching to the protocol the client asked for in `Upgrade`.
The handshake response for a WebSocket connection. Anything else using it is unusual.
The server has accepted the request but hasn't finished it.
A WebDAV code meant to stop clients timing out on long operations. Deprecated in practice — stream a response instead.
Preliminary headers — usually `Link` — sent before the final response.
Lets a browser start preloading stylesheets and fonts while your server is still assembling the page. Real, measurable, and badly underused.
The request was received, understood and accepted.
The request succeeded and the response carries the result.
The default for a successful GET, PUT, POST or PATCH that returns a body.
The request succeeded and created one or more new resources.
The right answer to a POST that creates something. Include a `Location` header pointing at the new resource.
The request was accepted but hasn't been acted on yet.
Asynchronous work — a job queued, a batch scheduled. Give the client a way to check on it, or 202 is just a shrug.
The response is a modified copy from a transforming proxy, not the origin's own.
You will almost never send this deliberately.
Success, and there is deliberately no body.
A DELETE that worked, or a PUT where returning the resource adds nothing. A 204 must not carry a body — some clients choke if it does.
Success; the client should reset the document view that sent the request.
A form-clearing convention from the pre-JavaScript era. Rare today.
The response carries only the byte range the client asked for.
Range requests — video seeking, resumable downloads. Requires a `Content-Range` header.
The body holds separate status codes for several independent operations.
WebDAV. Occasionally borrowed by batch APIs, though a plain 200 with per-item results is easier for clients.
Members of a binding were already enumerated in a previous part of the response.
WebDAV only.
The response is the result of applying instance manipulations to the resource.
Delta encoding. Effectively unused on the open web.
Further action is needed to complete the request. The choice between these is the most consequential decision in the whole table, because browsers cache permanent redirects effectively forever.
The resource has several representations and the client should pick one.
There is no standard way to present the choices, which is why nobody sends it.
The resource has a new permanent URL, given in `Location`.
Site migrations and canonical-host redirects. Browsers cache it aggressively — often until the profile is cleared — so a wrong 301 is very hard to undo. Clients may rewrite a POST to a GET when following it.
The resource is temporarily at a different URL.
Temporary moves. Like 301, it historically allows a POST to become a GET, which is why 307 exists.
Go and GET a different URL to see the result of this request.
The POST/redirect/GET pattern — the correct way to stop a form resubmitting on refresh. Always converts to a GET, by design.
The cached copy is still fresh; no body is sent.
The response to a conditional request carrying `If-None-Match` or `If-Modified-Since`. The single most effective bandwidth saving on the web.
The resource must be accessed through the proxy in `Location`.
Deprecated for security reasons. Do not send it; clients ignore it.
Reserved. Was defined in a previous version of the spec and is no longer used.
Nothing — the number is retired.
Temporarily elsewhere, and the method and body must not change.
The safe temporary redirect for APIs. Use it instead of 302 whenever a POST is involved.
Permanently elsewhere, and the method and body must not change.
The safe permanent redirect. Prefer it over 301 for API endpoints; 301 is still conventional for pages.
The request is faulty and repeating it unchanged will fail the same way. Getting these right is what makes an API debuggable by someone who didn't write it.
The server can't process the request because it is malformed.
Syntax-level failures — unparseable JSON, a missing required parameter. Not the catch-all for every validation error; 422 says more.
Authentication is required and has failed or not been supplied.
Misnamed — it means *unauthenticated*. Must include a `WWW-Authenticate` header naming the scheme.
Reserved for future use.
Increasingly used by APIs for quota and billing failures, and by paid-agent protocols. Not standardised for that, but the convention is settling.
The server understood the request and refuses to authorise it.
The caller is authenticated and still isn't allowed. Re-authenticating won't help — that's the difference from 401.
The server has no representation for this target.
Also a legitimate way to hide a resource's existence from someone not allowed to see it — but do that deliberately, not by accident.
The method is known but not supported on this resource.
Must include an `Allow` header listing the methods that are supported.
No representation matches the client's `Accept` headers.
Rare. Most servers sensibly serve their default representation instead of refusing.
Like 401, but the proxy is what needs credentials.
Sent by a proxy, with `Proxy-Authenticate`.
The server gave up waiting for the client to finish sending.
Idle connection cleanup. Distinct from 504, which is the server waiting on something upstream.
The request conflicts with the current state of the resource.
A duplicate unique key, an edit against a stale version. The body should explain the conflict well enough to resolve it.
The resource existed and has been permanently removed.
Stronger than 404 — it tells crawlers to drop the URL rather than keep retrying. Use it when you know something is deliberately deleted.
The request needs a `Content-Length` header and didn't have one.
Rare outside servers that refuse chunked uploads.
A conditional header — `If-Match`, `If-Unmodified-Since` — evaluated false.
Optimistic concurrency: the client's ETag no longer matches, so the write is refused rather than clobbering someone.
The request body is larger than the server will accept.
Upload limits. Formerly 'Payload Too Large'.
The request target is longer than the server will interpret.
Usually means a GET should have been a POST.
The body's format isn't supported for this resource.
A client sent `text/plain` where you require `application/json`. Very often the real cause of a mysterious 400.
The requested byte range lies outside the resource.
Range requests against a file that shrank.
The expectation in the `Expect` header can't be met.
Almost exclusively a failed `100-continue` negotiation.
The server refuses to brew coffee because it is, permanently, a teapot.
An April Fools' joke from RFC 2324 that shipped in enough implementations to survive attempts to reclaim the number. Not an IANA-registered HTTP status.
This server can't produce a response for the requested authority.
HTTP/2 connection coalescing sent the request to the wrong origin. The client should retry on a fresh connection.
The syntax is fine but the content is semantically wrong.
The right code for a failed validation: valid JSON, invalid values. More informative than a blanket 400.
The resource is locked.
WebDAV.
The request failed because a previous request it depended on failed.
WebDAV, and occasionally batch APIs.
The server won't risk processing a request that might be replayed.
TLS 1.3 0-RTT early data. Guards against an attacker replaying a captured request.
The client must switch to a different protocol.
Forcing a plaintext client onto TLS, with an `Upgrade` header naming the target.
The server requires the request to be conditional.
Forces clients to send `If-Match`, preventing lost updates from blind overwrites.
The client has sent too many requests in a given period.
Rate limiting. Always include `Retry-After` — without it a well-behaved client has to guess, and most guess badly.
The headers are too large to process.
Usually an oversized cookie. Worth logging which header blew the limit.
The resource is blocked as a result of a legal demand.
Court orders and takedowns. The number is a Fahrenheit 451 reference, and the RFC says so.
The server failed to fulfil an apparently valid request. Retrying may work; the client did nothing wrong.
An unexpected condition prevented the request from being fulfilled.
The catch-all. Every 500 in your logs is a bug or an unhandled dependency failure — none of them are normal.
The server doesn't support the functionality required.
An unrecognised method. Not the code for a feature you haven't shipped on a known endpoint — that's a 404 or a 405.
A gateway or proxy got an invalid response from upstream.
Your load balancer reached your app and got garbage, or nothing. Almost always means the origin crashed or never started.
The server is temporarily unable to handle the request.
Maintenance and overload. Include `Retry-After` so crawlers come back rather than de-indexing you.
A gateway timed out waiting for an upstream response.
The upstream is alive but too slow. Distinct from 502, where the response itself was invalid.
The server doesn't support the HTTP version used in the request.
Very rare in practice.
A content-negotiation configuration error on the server.
Transparent content negotiation. Effectively unused.
The server can't store the representation needed to complete the request.
WebDAV, and occasionally borrowed for quota failures.
The server detected an infinite loop while processing the request.
WebDAV binding cycles.
Further extensions to the request are required for the server to fulfil it.
An experimental extension framework that never took hold.
The client must authenticate to gain network access.
What a captive portal is supposed to send instead of hijacking a request. Almost none of them do.
This is a reference page, not a widget. Every status code the IANA registry lists is here, grouped by class, with the meaning, the situation it belongs in, and a link to the RFC section that defines it. Search filters the table as you type, and each code has its own anchor — so `#404` and `#429` are linkable straight into a code review or an incident doc.
The codes people get wrong cluster in two places. The redirects: 301 is permanent and gets cached by browsers effectively forever, 302 is temporary, 307 and 308 are the versions that preserve the request method, and picking 301 when you meant 302 is a mistake that outlives the person who made it. And the 4xx range: 401 means unauthenticated, 403 means authenticated-but-not-allowed, 404 means the resource doesn't exist, and 422 means the request was well-formed but semantically wrong — which is what most APIs should return for a failed validation, not 400.
The 1xx and some 5xx codes are worth knowing even if you'll never send one. 103 Early Hints lets a server push resource hints before the real response. 425 Too Early guards against replayed 0-RTT requests. 511 Network Authentication Required is what a captive portal is supposed to send and almost never does.
Everything on this page is in the server-rendered HTML — no filtering step hides a code from a crawler, and nothing here needs JavaScript to read. That's deliberate: it's the page on this site most likely to be quoted by an answer engine, and it's built the way we tell everyone else to build.
Both are permanent redirects. A 301 historically allowed clients to change a POST into a GET when following it, and most do. A 308 forbids that — the method and body are preserved. Use 308 for API endpoints and 301 for pages, where the GET-rewriting behaviour is what you want anyway.
422 Unprocessable Content, if the request parsed correctly and only the meaning was wrong — valid JSON with an email field that isn't an email. Reserve 400 for requests that are malformed at the protocol or syntax level. Both are widely accepted; 422 tells the client more.
401 Unauthorized means we don't know who you are — send credentials. It must come with a `WWW-Authenticate` header. 403 Forbidden means we know who you are and you still can't have this. Returning 404 instead of 403 to hide a resource's existence is a legitimate pattern, but do it deliberately.
429 Too Many Requests, with a `Retry-After` header giving either seconds or an HTTP date. Without `Retry-After`, a well-behaved client has to guess, and most guess badly.
It's real in the sense that it's defined — in RFC 2324, an April Fools' joke from 1998 — and real in the sense that enough implementations shipped it that attempts to reclaim the code number were rejected. It is not registered with IANA as a usable status.