Tool

HTTP status.

Every HTTP status code currently registered with IANA, sourced from RFC 9110 (the unified HTTP semantics RFC, 2022) and its predecessors. Search by number, name, or description; filter by category. The reference you grep when you forget what 422 actually means.

Total codes
51
Showing
51

Codes
100
Continue RFC 9110 §15.2.1
Server received the request headers and the client should proceed to send the request body.
101
Switching Protocols RFC 9110 §15.2.2
The server is switching protocols at the client's request — used for WebSocket upgrades.
102
Processing RFC 2518
WebDAV: server has received and is processing the request, but no response is available yet.
103
Early Hints RFC 8297
Used to return preliminary headers (typically Link headers for preload) before the final response.
200
OK RFC 9110 §15.3.1
Standard response for successful HTTP requests. Body contains the requested resource.
201
Created RFC 9110 §15.3.2
Request succeeded and a new resource was created. Location header should point to the new URL.
202
Accepted RFC 9110 §15.3.3
Request accepted for processing but not yet completed. Used for long-running async operations.
203
Non-Authoritative Information RFC 9110 §15.3.4
Response is from a transforming proxy, not the origin server.
204
No Content RFC 9110 §15.3.5
Request succeeded but there is no content to return. Often used after PUT/DELETE.
205
Reset Content RFC 9110 §15.3.6
Tells the client to reset the document view.
206
Partial Content RFC 9110 §15.3.7
Response to a Range request — server is returning only part of the resource.
207
Multi-Status RFC 4918
WebDAV: response body contains multiple statuses for separate operations.
300
Multiple Choices RFC 9110 §15.4.1
Multiple options for the resource — rare in modern APIs.
301
Moved Permanently RFC 9110 §15.4.2
Resource has moved to a new URL. Browsers and search engines update their bookmarks.
302
Found RFC 9110 §15.4.3
Temporary redirect. Originally meant to preserve the method but most clients change POST to GET — use 307 for strict preservation.
303
See Other RFC 9110 §15.4.4
After a POST, redirect with GET to the result. The PRG (Post-Redirect-Get) pattern.
304
Not Modified RFC 9110 §15.4.5
Cached response is still valid. Sent when If-Modified-Since or If-None-Match conditions match.
307
Temporary Redirect RFC 9110 §15.4.8
Same as 302 but the method must not change — POST stays POST.
308
Permanent Redirect RFC 9110 §15.4.9
Same as 301 but the method must not change.
400
Bad Request RFC 9110 §15.5.1
Server cannot process the request due to a client error — malformed syntax, invalid framing, missing required fields.
401
Unauthorized RFC 9110 §15.5.2
Authentication required and has failed or not been provided. Misnomer — actually means "unauthenticated".
402
Payment Required RFC 9110 §15.5.3
Reserved for future use. Stripe and a few APIs use it for billing-related failures.
403
Forbidden RFC 9110 §15.5.4
Server understood the request but refuses to authorize it. Distinct from 401: the user is identified but not permitted.
404
Not Found RFC 9110 §15.5.5
Resource does not exist on the server. Most famous status code on the internet.
405
Method Not Allowed RFC 9110 §15.5.6
The HTTP method is not supported for this resource. Response should include Allow header.
406
Not Acceptable RFC 9110 §15.5.7
Server cannot produce a response matching the Accept headers from the client.
408
Request Timeout RFC 9110 §15.5.9
Client did not produce a request within the time the server was prepared to wait.
409
Conflict RFC 9110 §15.5.10
Request conflicts with the current state of the resource — for example, a duplicate key on insert.
410
Gone RFC 9110 §15.5.11
Resource is permanently unavailable, with no forwarding address. Used to actively de-list URLs.
411
Length Required RFC 9110 §15.5.12
Server requires Content-Length header.
412
Precondition Failed RFC 9110 §15.5.13
A precondition (If-Match, If-Unmodified-Since) was not met.
413
Content Too Large RFC 9110 §15.5.14
Request body exceeds the server's configured limit. Was "Payload Too Large" pre-RFC 9110.
414
URI Too Long RFC 9110 §15.5.15
Request URI is longer than the server is willing to process. Often hit by GETs that should be POSTs.
415
Unsupported Media Type RFC 9110 §15.5.16
Server does not support the media type sent in Content-Type. Common with PATCH dispatch.
418
I'm a teapot RFC 2324
April Fools' RFC 2324 (1998). Some servers return it — Google's teapot endpoint is the canonical reference.
422
Unprocessable Content RFC 9110 §15.5.21
Request was well-formed but semantically invalid. Common in WebDAV and JSON-API responses.
425
Too Early RFC 8470
Server unwilling to risk processing a request that might be replayed.
426
Upgrade Required RFC 9110 §15.5.22
Client should switch to a different protocol — typically TLS.
428
Precondition Required RFC 6585
Server requires the request to be conditional — prevents lost-update problems.
429
Too Many Requests RFC 6585
Client has sent too many requests in a given window. Should include Retry-After header.
431
Request Header Fields Too Large RFC 6585
Total size of request headers exceeds the server's limit.
451
Unavailable For Legal Reasons RFC 7725
Resource cannot be served for legal reasons — court orders, geo-blocks. Number references Bradbury's Fahrenheit 451.
500
Internal Server Error RFC 9110 §15.6.1
Generic server-side error. The catch-all for anything the server doesn't know how to classify.
501
Not Implemented RFC 9110 §15.6.2
Server does not support the functionality required to fulfill the request.
502
Bad Gateway RFC 9110 §15.6.3
Server acting as a gateway received an invalid response from the upstream. Common with misconfigured proxies.
503
Service Unavailable RFC 9110 §15.6.4
Server is temporarily unable to handle the request — overloaded or down for maintenance.
504
Gateway Timeout RFC 9110 §15.6.5
Gateway did not receive a timely response from the upstream server.
505
HTTP Version Not Supported RFC 9110 §15.6.6
Server does not support the HTTP protocol version used in the request.
507
Insufficient Storage RFC 4918
WebDAV: server has run out of space.
508
Loop Detected RFC 5842
WebDAV: server detected an infinite loop while processing the request.
511
Network Authentication Required RFC 6585
Used by captive portals — Wi-Fi login screens — to indicate the client needs to authenticate.

Why the first digit matters.

HTTP status codes are three-digit integers from 100 to 599, partitioned into five categories by the first digit. The categorisation is not arbitrary — it dates to RFC 1945 (HTTP/1.0, 1996) and tells the client how to react before parsing the response body. A client receiving a 5xx code can retry; a client receiving a 4xx code shouldn't (the request itself is wrong, retrying without modification will fail again). A 3xx tells the client to follow a Location header; a 2xx tells it to consume the body as-is.

1xx informational codes are intermediate — the server has received the request headers and is signalling state without ending the exchange. 100 Continue tells a client that started uploading a large body to keep going. 101 Switching Protocols is what a server returns when a WebSocket Upgrade is accepted. 103 Early Hints (RFC 8297, 2017) is the newest and most underused: it lets the server send Link preload headers before the final response is ready, giving the browser a head start on fetching CSS and JavaScript while the dynamic page is still being assembled. CDNs (Cloudflare, Fastly) and frameworks (Next.js, SvelteKit) increasingly support 103 in 2024.

2xx success means the request was received, understood, and accepted. 200 OK is the workhorse. 201 Created should follow a successful POST that creates a resource (with a Location header pointing to the new URL). 204 No Content should follow a successful PUT or DELETE where the server has nothing to return. 206 Partial Content is the response to a Range request — what video players use to seek into a file without re-downloading from the start.

3xx redirection tells the client the resource lives somewhere else. The four-way distinction between 301/302/307/308 is the single most-confused area of HTTP. 301 and 308 are permanent (browsers and search engines update bookmarks); 302 and 307 are temporary. 301 and 302 historically allowed clients to switch the request method (POST → GET), which broke API behaviour; 307 and 308 explicitly forbid that change. For new APIs, prefer 308 for permanent and 307 for temporary; for human-facing redirects after a POST, use 303 See Other to explicitly turn the redirect into a GET.

4xx client errors indicate the request itself was wrong. 400 Bad Request is the catch-all; specific codes (401, 403, 404, 405, 409, 422, 429) cover named cases. The boundary between 400 and 422 is fuzzy — RFC 9110 says 400 is for malformed syntax and 422 is for "well-formed but semantically invalid", but most APIs use 400 broadly and 422 only when they want to signal validation errors specifically.

5xx server errors indicate the server's failure to handle a valid request. 500 is the catch-all. 502 Bad Gateway and 504 Gateway Timeout indicate failures in proxies or load balancers between the client and origin. 503 Service Unavailable signals temporary unavailability (planned maintenance, overload). 5xx responses are the right time to retry with exponential backoff; 4xx responses are not, because retrying without modifying the request will produce the same error.

From a tower of RFCs to one.

For most of HTTP's history, the spec was scattered across many documents. RFC 2616 (1999) was the original HTTP/1.1 — a single large document. RFC 7230 through 7235 (2014) split it into six focused RFCs covering message syntax, semantics, conditional requests, range requests, caching, and authentication. RFC 9110 (June 2022) re-unified the semantic layer: status codes, methods, headers, and the data model all live in one document again. The split-out RFCs 9111 (caching) and 9112 (HTTP/1.1 message syntax) handle the lower-level details.

RFC 9110 is the document to cite for any modern HTTP semantic question. It deprecates a handful of codes (303 has slightly cleaner semantics; some 4xx codes were renamed for clarity — 413 went from "Payload Too Large" to "Content Too Large"; 416 "Range Not Satisfiable" was tightened). It also formalises practices that were already universal — the requirement that 3xx responses include a Location header, the recommendation that 429 responses include a Retry-After header.

A handful of status codes live outside the core RFCs. 418 "I'm a teapot" comes from RFC 2324, an April Fools' joke from 1998 that some servers implement. 451 "Unavailable for Legal Reasons" (RFC 7725, 2016) honours Ray Bradbury's Fahrenheit 451 and is the right code for content removed under court order or geo-blocked for regulatory reasons. The IANA HTTP Status Code Registry is the authoritative list of every registered code; codes not in the registry should not be used in production.

The five most-mishandled codes in real APIs.

200 for everything. The single most common API anti-pattern is to return 200 OK regardless of outcome, with the actual error in the response body. {"status": "error", "message": "user not found"} with HTTP 200 makes monitoring useless — you can't alert on 4xx/5xx rates because there aren't any. Use the right status code; put structured error details in the body via RFC 7807 Problem Details. The body and the status work together.

401 vs 403 confusion. 401 means "you're not authenticated" — the request lacks credentials, and adding them might succeed. 403 means "you're authenticated but not authorised" — credentials won't help. Many APIs return 401 for both cases, which conflates "log in" with "you can't do this". The fix: check the Authorization header first; if missing or invalid, return 401; if valid but lacks permission, return 403.

404 for permission denials. Some APIs return 404 instead of 403 to avoid confirming that a resource exists. This is "security through obscurity" with real costs — your client cannot distinguish a missing resource from a permission issue, which makes debugging painful. The HTTP spec says you can do this, but most modern guidance is to be explicit: 403 means "this exists but you can't see it", 404 means "this doesn't exist". Pick one consistently.

500 instead of 4xx. A failed validation that should return 400 or 422 sometimes returns 500 because the server-side validation throws an unhandled exception that the framework converts to 500. The client retries (5xx is retryable), gets the same error, and writes a bug report. The fix: catch validation errors at the API boundary and translate them into the correct 4xx code with a structured error body.

302 instead of 303. The Post-Redirect-Get pattern (handle a form POST, then redirect to a GET that displays the result) needs 303 See Other, which explicitly tells the client to use GET on the new URL. 302 historically allowed the client to keep the POST method, which is wrong for PRG. Most modern frameworks default to the right code, but legacy code often gets this wrong, leading to subtle double-submission bugs.

Which codes should you retry?

The first-digit rule is the right starting point: retry 5xx, don't retry 4xx. The exceptions matter. 408 Request Timeout is a 4xx but should be retried — the server is telling you it gave up waiting. 429 Too Many Requests is a 4xx and should be retried, but only after honouring the Retry-After header. 425 Too Early is the rare 4xx that explicitly invites a retry. Among 5xx codes, 501 Not Implemented should not be retried — the server doesn't support what you're asking, and that won't change without a code deploy.

For idempotent methods (GET, HEAD, PUT, DELETE), retrying any 5xx is safe. For non-idempotent methods (POST), retries can cause duplicate effects. Stripe's idempotency-key pattern — the client generates a UUID per request, the server caches the response under that key, retries with the same key get the cached response — is the standard solution. Most modern APIs (Stripe, GitHub, Square) implement idempotency keys for unsafe methods.

Backoff strategy matters more than the binary retry-or-not decision. Exponential backoff with jitter — wait 2^n × random_factor between retries — prevents thundering herds when many clients receive errors simultaneously. AWS SDK, Google Cloud SDK, and most production HTTP clients implement exponential backoff with jitter as the default. Cap the maximum delay (typically 30s) and the maximum retry count (typically 5–10) to bound worst-case latency. The Retry Strategy simulator visualises the interactions.

Found this useful?