Skip to content
FormatKit

Free HTTP status code reference

HTTP status codes, and which one to send

This reference is free and needs no signup: all 63 registered HTTP status codes from 100 Continue to 511 Network Authentication Required, each with its name, the RFC section that defines it today, what it asserts, and the neighbouring code people send by mistake. Type a number into the box to jump straight to one, or read the chart — it is plain HTML, so find-on-page works and nothing needs to load first. Beyond the registry it also covers the 16 vendor codes that fill real logs, from nginx 499 to Cloudflare 524.

  • 100% free
  • No signup
  • 63 registered codes
  • RFC 9110 sections
  • Works with JS off
Common:

Type a number and the definition appears here. The full chart below is plain HTML, so it is also searchable with your browser’s own find-on-page and readable with JavaScript off.

The full status code chart

Five classes, 63 codes. The first digit is the only part a client is obliged to understand: a cache that has never heard of 308 still knows it is a redirect, which is what made adding codes to HTTP possible at all. Rows marked cacheable may be stored by a shared cache even when you send no Cache-Control header.

1xx informational

Interim responses. The connection stays open and a final status still follows, which is why most application frameworks never let you send one directly.

1xx informational status codes with name, defining RFC section, meaning and guidance on when to send each one
CodeNameDefined inWhat it meansWhen to send it
100ContinueRFC 9110 §15.2.1The request headers were accepted; send the body now.Sent by the server in reply to an Expect: 100-continue header, never invented by application code. It exists so a client can avoid pushing a 2 GB upload at an endpoint that would have rejected the headers anyway.
101Switching ProtocolsRFC 9110 §15.2.2The server is changing to the protocol named in the Upgrade header.The last HTTP/1.1 status a WebSocket connection ever sees — after it, the bytes on the socket are frames, not HTTP. HTTP/2 has no upgrade dance, so a WebSocket over h2 uses an extended CONNECT and a plain 200 instead.
102ProcessingdormantRFC 2518 §10.1The WebDAV request is still running; do not time out.A keep-alive ping for long WebDAV operations, deliberately dropped when RFC 4918 replaced RFC 2518 in 2007. It survives in the IANA registry and nowhere else — reach for 202 with a status URL instead.
103Early HintsRFC 8297Preliminary Link headers, sent before the real response.Send it while your origin is still assembling the page so the browser can start fetching stylesheets and fonts named in Link: rel=preload. Chrome, Firefox and Safari all act on it; the win is measured in the hundreds of milliseconds a slow origin spends thinking.

2xx success

The request was received, understood and accepted. The differences between them are about what the response body contains and what the client should do with its current page.

2xx success status codes with name, defining RFC section, meaning and guidance on when to send each one
CodeNameDefined inWhat it meansWhen to send it
200OKcacheableRFC 9110 §15.3.1The request succeeded and the body is the result.The default, and the one to stop overusing: an API that answers 200 with {"error": …} inside defeats every retry policy, cache and monitoring dashboard downstream. What the body means depends on the method — for GET it is the resource, for POST it is a description of what happened.
201CreatedRFC 9110 §15.3.2One or more resources now exist that did not before.Pair it with a Location header pointing at the new resource, which is the half most APIs forget. A PUT that overwrites an existing resource returns 200 or 204; only the call that brought something into being returns 201.
202AcceptedRFC 9110 §15.3.3The request was queued, and the outcome is not known yet.The honest answer for anything that hands work to a queue: video encoding, bulk imports, sending mail. Return a body or Location that lets the client poll for the result, because 202 promises nothing about whether the work will ultimately succeed.
203Non-Authoritative InformationcacheableRFC 9110 §15.3.4A proxy modified the payload the origin sent.Emitted by transforming proxies — an image compressor or an annotation gateway — not by your application. Seeing it in a client log means something between you and the origin rewrote the body.
204No Contentcacheableno bodyRFC 9110 §15.3.5It worked and there is deliberately nothing to send back.The right answer to a DELETE that succeeded or a PUT that changed nothing visible. A 204 must carry no body at all — not an empty JSON object, not a newline — and browsers will not navigate away from the current page when they receive one.
205Reset Contentno bodyRFC 9110 §15.3.6Succeeded; clear the form the user just submitted.Like 204 but with an instruction attached: reset the document view, typically a data-entry form, so the next record can be typed. Almost extinct outside intranet applications, and like 204 it carries no body.
206Partial ContentcacheableRFC 9110 §15.3.7The body is the byte range the client asked for.The status behind resumable downloads and video seeking, sent in reply to a Range header and required to carry Content-Range. Answering a Range request with a plain 200 is legal but forces the client to re-download from byte zero.
207Multi-StatusRFC 4918 §11.1One response body holding a separate status per sub-resource.WebDAV's answer to bulk operations: the outer status is 207 and the XML body reports 200, 403 or 424 per member. Useful as a design pattern for any batch endpoint, though outside WebDAV you are inventing the body format yourself.
208Already ReportedRFC 5842 §7.1This member was already listed earlier in the same 207 body.Exists purely to stop a WebDAV binding loop from repeating an entire subtree in one Multi-Status response. You will never send it by hand.
226IM UseddormantRFC 3229 §10.4.1The body is a delta against a copy the client already holds.Delta encoding for HTTP, proposed in 2002 and effectively never deployed. The idea returned as HTTP compression dictionaries rather than as this status.

3xx redirection

Further action is needed to complete the request. Four of these nine codes are redirects a browser follows, and the split between them is about method rewriting and cache lifetime.

3xx redirection status codes with name, defining RFC section, meaning and guidance on when to send each one
CodeNameDefined inWhat it meansWhen to send it
300Multiple ChoicescacheableRFC 9110 §15.4.1Several representations exist; the client picks one.Agent-driven content negotiation, which browsers never implemented a UI for. The practical use is a machine-readable list of alternatives at a versioned API root.
301Moved PermanentlycacheableRFC 9110 §15.4.2The resource has a new URL and always will.Use for domain moves, http→https and trailing-slash canonicalisation, where search engines should transfer ranking signals to the target. Two consequences bite: browsers cache it aggressively and by default indefinitely, and clients are permitted to rewrite POST to GET — send 308 when the method must survive.
302FoundRFC 9110 §15.4.3The resource is temporarily somewhere else.The default in most frameworks and rarely the code you actually mean. Every browser rewrites POST to GET on a 302 even though the spec forbids it, so the standard split it into 303 (rewrite the method, deliberately) and 307 (never rewrite it).
303See OtherRFC 9110 §15.4.4Go and GET this other URL to see the result.The correct end of a POST-Redirect-GET cycle: the form submission succeeded, and the client must fetch the confirmation page with GET so a browser refresh cannot resubmit the order. Method rewriting is the point of this code, not an accident of it.
304Not Modifiedno bodyRFC 9110 §15.4.5Your cached copy is still current; reuse it.Answers a conditional GET carrying If-None-Match or If-Modified-Since. It must have no body and must repeat the validators, and it is the reason a well-tuned site can serve a 200 KB page in a 150-byte response.
305Use ProxydormantRFC 9110 §15.4.6Repeat the request through the proxy in Location.Deprecated for being a security hazard — it let any server redirect a client through a machine of the server's choosing. Browsers ignore it.
306(Unused)dormantRFC 9110 §15.4.7Reserved; was 'Switch Proxy' in a 1998 draft.Reserved by the standard and permanently unassigned. Nothing may use it, which makes it a small reminder that gaps in the numbering are deliberate.
307Temporary RedirectRFC 9110 §15.4.8Temporarily elsewhere, and keep the method and body.302 with the ambiguity removed: a POST redirected with 307 arrives at the target as a POST with the same body. Use it for maintenance windows, regional failover and A/B routing where the client must not silently turn a write into a read.
308Permanent RedirectcacheableRFC 9110 §15.4.9Permanently elsewhere, and keep the method and body.The one to use for a permanent API move, because 301 lets a client turn the POST into a GET and lose the body. It is also what the HSTS preload list effectively assumes; support landed in every browser by 2016.

4xx client error

The request is at fault and repeating it unchanged will fail again. Picking precisely here is what lets a client library retry, re-authenticate or give up without guessing.

4xx client error status codes with name, defining RFC section, meaning and guidance on when to send each one
CodeNameDefined inWhat it meansWhen to send it
400Bad RequestRFC 9110 §15.5.1The request itself is malformed and cannot be parsed.Reserve it for syntax: truncated JSON, a header the parser choked on, a query string that is not valid percent-encoding. A body that parses cleanly but fails your business rules is 422, and using 400 for both denies the client any way to tell a typo from a rejected value.
401UnauthorizedRFC 9110 §15.5.2No valid credentials were supplied — authenticate and retry.Misnamed: it means unauthenticated. It is the only 4xx that is required to carry a WWW-Authenticate header naming the scheme, and omitting that header is the most common way a 401 confuses a client library into not retrying with a refreshed token.
402Payment RequiredRFC 9110 §15.5.3Reserved for future use.Never standardised, but adopted in practice by Stripe, GitHub and several API gateways for 'your plan does not cover this'. Nothing in the ecosystem agrees on the body format, so document yours.
403ForbiddenRFC 9110 §15.5.4The server understood who you are and refuses anyway.Send it when authentication succeeded but authorisation failed, and repeating the request with better credentials of the same identity will not help. Where even acknowledging the resource exists leaks information, 404 is the accepted substitute.
404Not FoundcacheableRFC 9110 §15.5.5No representation exists for this target, and no reason is given.Deliberately non-committal: the resource may never have existed, may be hidden, may be back tomorrow. Heuristically cacheable, which surprises people whose freshly deployed route stays missing for a minute behind a CDN.
405Method Not AllowedcacheableRFC 9110 §15.5.6The URL exists but not for this method.Must include an Allow header listing the methods that do work — a 405 without it is a spec violation and a dead end for the caller. A method you have never heard of is 501, not 405.
406Not AcceptableRFC 9110 §15.5.7Nothing you can produce matches the Accept header.The spec explicitly allows ignoring Accept and sending your default representation instead, which is what most servers sensibly do. Sending 406 because a client asked for text/csv and you only have JSON is correct but rarely helpful.
407Proxy Authentication RequiredRFC 9110 §15.5.8The proxy in front of the server wants credentials.401's counterpart one hop earlier, carrying Proxy-Authenticate rather than WWW-Authenticate. If your CI jobs fail with this, the fix is in the runner's proxy configuration, not in the application.
408Request TimeoutRFC 9110 §15.5.9The client took too long to finish sending the request.Sent when an idle connection is reaped mid-request, which makes it one of the few 4xx codes worth retrying automatically. Do not use it for a request that arrived fine and then took too long to process — that is 504 or a 503 with Retry-After.
409ConflictRFC 9110 §15.5.10The request collides with the current state of the resource.The right code for a duplicate signup, a stale optimistic-lock version or a branch that cannot fast-forward. The body should say what conflicts, because 409 promises the client could resolve it and resubmit.
410GonecacheableRFC 9110 §15.5.11It existed, it was removed on purpose, and it is not coming back.Stronger and more useful than 404 when you control the history: Google drops a 410 URL from the index faster than a 404, and crawlers stop retrying sooner. Only send it when the removal is deliberate and permanent.
411Length RequiredRFC 9110 §15.5.12Refusing a request body that arrived without Content-Length.Sent by servers that will not accept chunked transfer encoding on uploads, usually for quota enforcement. In HTTP/2 and HTTP/3 there is no chunked encoding at all, so this code is largely an HTTP/1.1 artefact.
412Precondition FailedRFC 9110 §15.5.13An If-Match or If-Unmodified-Since condition was false.The engine behind safe concurrent writes: the client sends If-Match with the ETag it read, and 412 means someone else changed the resource first. Answer with the current ETag so the client can re-read, merge and retry.
413Content Too LargeRFC 9110 §15.5.14The request body exceeds what the server will accept.Renamed from 'Payload Too Large' in RFC 9110. Usually thrown by the reverse proxy rather than your application — nginx client_max_body_size defaults to 1 MB — so check the proxy before debugging the handler.
414URI Too LongcacheableRFC 9110 §15.5.15The request target exceeds what the server will parse.Nearly always a GET that should have been a POST, or a redirect loop appending a parameter each time round. Common ceilings: nginx 8 KB per request line, Apache 8,190 bytes, IIS 16 KB.
415Unsupported Media TypeRFC 9110 §15.5.16The body's Content-Type is one this endpoint cannot read.About the request, where 406 is about the response. The classic cause is a curl command with -d and no header, because curl then labels the body application/x-www-form-urlencoded and a JSON API rejects it.
416Range Not SatisfiableRFC 9110 §15.5.17The requested byte range lies outside the resource.Send Content-Range: bytes */<length> with it so the client learns the real size and can ask again. A media player that stalls at the end of a file is often looking at one of these.
417Expectation FailedRFC 9110 §15.5.18The Expect header asked for something unsupported.In practice always about Expect: 100-continue. Some clients retry without the header on receiving it, which is why the failure often looks like a one-off latency spike rather than an error.
418I'm a TeapotdormantRFC 2324 §2.3.2The entity is a teapot and cannot brew coffee.From the Hyper Text Coffee Pot Control Protocol, an April Fools' RFC from 1998 that RFC 7168 extended to teapots. RFC 9110 lists 418 as reserved and unusable precisely because the joke made it too well known to reassign, and Node, Go and Rust all ship the constant.
421Misdirected RequestRFC 9110 §15.5.20This server cannot produce a response for that authority.An HTTP/2 phenomenon: browsers coalesce connections when one certificate covers several hostnames, so a request for a.example.com can arrive on a connection opened to b.example.com. Returning 421 tells the client to open a fresh connection and retry.
422Unprocessable ContentRFC 9110 §15.5.21The syntax is fine but the content is semantically wrong.The validation-failure code: well-formed JSON whose email field is not an email, or whose end date precedes its start date. Promoted from WebDAV into core HTTP by RFC 9110, so it no longer needs an apology in an API design review.
423LockedRFC 4918 §11.3The resource is locked by a WebDAV LOCK.WebDAV-specific, but reused by document editors and CMSes for 'someone else has this open'. Say who holds the lock and until when, or the client can only poll.
424Failed DependencyRFC 4918 §11.4This step failed because an earlier one in the same request did.Appears inside 207 bodies for batch operations, and has been borrowed by transactional APIs to mark the steps that were never attempted. It says nothing was wrong with this step itself.
425Too EarlyRFC 8470 §5.2Refusing a request replayed from TLS 1.3 early data.0-RTT data can be captured and replayed by an attacker, so a server rejects non-idempotent requests that arrive in it. The client retries once the handshake completes, which costs one round trip and removes the replay window.
426Upgrade RequiredRFC 9110 §15.5.22Use a different protocol version to talk to this endpoint.Must carry an Upgrade header naming what to switch to. Its live use is forcing TLS or a newer HTTP version on a plaintext client, not versioning your own API.
428Precondition RequiredRFC 6585 §3The request must be conditional; send If-Match.Closes the lost-update hole by refusing unconditional writes outright, rather than waiting for two clients to overwrite each other. Pair it with 412: 428 demands the precondition, 412 reports that it failed.
429Too Many RequestsRFC 6585 §4The client exceeded a rate limit.Send Retry-After — as seconds or an HTTP date — or every client will invent its own backoff, and the aggressive ones will win. RFC 9110 does not define RateLimit headers; the draft-standard RateLimit-Limit and RateLimit-Remaining are still an Internet-Draft.
431Request Header Fields Too LargeRFC 6585 §5The headers, or one of them, are too big to process.In the wild this is nearly always a cookie jar that grew past the server's 8 KB header budget. The fix that actually works is clearing cookies for the domain; raising the limit only postpones it.
451Unavailable For Legal ReasonsRFC 7725 §3Access is denied because of a legal demand.Numbered after Fahrenheit 451 and intended to be visible to researchers measuring censorship. The response should identify the blocking authority in a Link header with rel="blocked-by".

5xx server error

The server failed to fulfil an apparently valid request. Only these codes and 408, 425 and 429 are safe to retry automatically, and only for idempotent methods.

5xx server error status codes with name, defining RFC section, meaning and guidance on when to send each one
CodeNameDefined inWhat it meansWhen to send it
500Internal Server ErrorRFC 9110 §15.6.1An unhandled failure — the server has no better description.The catch-all, and a sign of a missing branch whenever it appears in a log with a known cause. Never leak a stack trace in the body; put a correlation id there instead so support can find the trace you kept server-side.
501Not ImplementedcacheableRFC 9110 §15.6.2The server does not support the method at all, for any resource.Server-wide, unlike 405 which is per-resource: a server that has never heard of PROPFIND answers 501, while one that knows PATCH but not on this URL answers 405. It is heuristically cacheable, which is why a proxy can keep answering it after you deploy the feature.
502Bad GatewayRFC 9110 §15.6.3An upstream server returned something invalid.Read it as 'the proxy reached your application and disliked the answer' — the process crashed mid-response, closed the socket, or spoke something that was not HTTP. Look at the origin's logs, not the proxy's.
503Service UnavailableRFC 9110 §15.6.4Temporarily unable to handle the request, by design.The only correct status for planned maintenance and for shedding load, and the only 5xx that search engines treat as temporary rather than a defect. Always attach Retry-After; without it, crawlers and clients guess.
504Gateway TimeoutRFC 9110 §15.6.5An upstream server did not answer in time.The distinction from 502 is worth keeping: 504 means the origin was still thinking when the proxy gave up, so the work may well have completed afterwards. That makes blind retries of non-idempotent requests dangerous here.
505HTTP Version Not SupportedRFC 9110 §15.6.6The major HTTP version in the request line is unsupported.Rare enough that seeing one usually means a protocol-confusion attempt or a client speaking plaintext HTTP/2 to an HTTP/1.1-only port.
506Variant Also NegotiatesdormantRFC 2295 §8.1Content negotiation is misconfigured into a loop.From the experimental transparent content negotiation spec: a chosen variant is itself a negotiation resource, so the server would negotiate forever. Effectively an Apache mod_negotiation configuration error.
507Insufficient StorageRFC 4918 §11.5The server cannot store the representation needed to finish.Literally out of disk or over a quota, for WebDAV and for storage APIs that borrowed it. It says the failure is about capacity, not about your request, so a retry after cleanup is reasonable.
508Loop DetectedRFC 5842 §7.2An infinite loop was found while processing the request.The WebDAV binding extension's guard against a directory tree that contains itself. Terminates a request that would otherwise run until the process died.
510Not ExtendeddormantRFC 2774 §7The request needs an extension the server requires but did not get.From the experimental HTTP Extension Framework, which never shipped; IANA has since marked it obsolete. Nothing should return it today.
511Network Authentication RequiredRFC 6585 §6A captive portal is intercepting the connection.Intended for hotel and airport Wi-Fi so that a client can tell a portal from the real origin, instead of caching the login page under your URL. It is defined for the intercepting proxy to send — an origin server must never return it.

Which one do I send?

Thirteen decisions that account for most of the status codes changed in code review. The right-hand column is the consequence of getting it backwards, which is usually invisible in development and expensive in production.

Situations paired with the status code to send, the code commonly sent instead, and the consequence of the wrong choice
SituationSendOften sentWhat goes wrong
A page moved to a new URL for good301302302 tells crawlers to keep the old URL indexed, so ranking signals never transfer to the new one.
A POST endpoint moved to a new URL for good308301A client is allowed to turn a 301-redirected POST into a GET, which silently drops the request body.
Traffic is being diverted during a deploy307302307 guarantees the method and body survive; every browser rewrites a redirected POST to GET on 302.
A form was submitted and the result should be a page303200Answering the POST directly leaves the browser able to resubmit the order on refresh; 303 sends it to a GET.
The caller sent no token, or an expired one401403401 plus WWW-Authenticate is the signal that makes a client library refresh the token and retry.
The caller is authenticated but lacks the role403401401 invites the client to try new credentials, which sends it into a refresh loop it can never win.
JSON that parses but fails validation422400400 also covers unparseable bytes, so the caller cannot tell a broken payload from a rejected value.
The body is truncated or not valid JSON at all400422422 says the syntax was fine, which sends the caller looking for a field error that does not exist.
The resource was deliberately deleted410404410 gets the URL dropped from a search index faster and stops well-behaved crawlers from retrying.
The URL exists but not for DELETE405404405 with an Allow header tells the caller which methods do work; 404 implies the path itself is wrong.
Planned maintenance, back in ten minutes503500503 with Retry-After is the only 5xx that search engines and clients treat as temporary by design.
The upstream never answered in time504502502 means the answer was invalid; 504 means it never arrived, so the work may still be running.
The client hit its rate limit429503429 is about this caller and carries a per-caller Retry-After; 503 says the whole service is down.

Codes in your logs that are in no standard

Servers and proxies mint their own numbers, and IANA has never seen any of these 16. Two are not even sent to a client: nginx 444 closes the connection instead of responding, and 499 is written to the access log after the client has already gone.

Non-standard HTTP status codes with the software that emits them and what each one indicates
CodeNameEmitted byWhat it tells you
218This Is FineApache Web ServerUsed by mod_proxy when an error is swallowed and the response is sent anyway. Named after the cartoon.
419Page ExpiredLaravelThe CSRF token in the form no longer matches the session. Reloading the form fixes it; the code is not registered with IANA.
440Login Time-outMicrosoft IISThe session expired and the client must authenticate again. Outlook Web Access is where most people meet it.
444No ResponsenginxAn internal instruction, never sent on the wire: nginx closes the connection with no response at all, which is how requests are dropped silently.
460Client Closed ConnectionAWS Elastic Load BalancingThe client disconnected before the load balancer could respond. Logged by the ALB, not returned to anyone.
463Too Many IPs in X-Forwarded-ForAWS Elastic Load BalancingMore than 30 addresses in the X-Forwarded-For header, which usually means a proxy loop.
494Request Header Too Largenginxnginx's internal code before it converts the failure into a 400 for the client. Raise large_client_header_buffers if it is legitimate.
495SSL Certificate ErrornginxThe client certificate presented could not be verified, in mutual-TLS setups.
497HTTP Request Sent to HTTPS PortnginxA plaintext request arrived on a TLS listener — usually a hard-coded http:// URL against a port that only speaks https.
499Client Closed RequestnginxThe single most misread line in an nginx access log: the client gave up first, so a spike of 499s usually means your origin got slow, not that clients broke.
520Web Server Returned an Unknown ErrorCloudflareThe origin answered with something Cloudflare could not parse — an empty reply, oversized headers, or a connection reset mid-response.
521Web Server Is DownCloudflareThe origin refused the TCP connection. Nine times out of ten the origin firewall is blocking Cloudflare's IP ranges.
522Connection Timed OutCloudflareThe TCP handshake with the origin never completed within 15 seconds, which points at packet loss or a saturated origin rather than at application code.
524A Timeout OccurredCloudflareThe connection succeeded but the origin did not finish responding within 100 seconds on the free and pro plans. Move long work behind a job queue and answer with 202.
525SSL Handshake FailedCloudflareThe TLS handshake between Cloudflare and the origin failed — no shared cipher suite, or an origin certificate the chosen SSL mode rejects.
530Origin DNS ErrorCloudflareAlways accompanied by a 1xxx error code in the body, and the 1xxx number is the one that tells you what actually broke.

How to use this status code reference

One number in, one definition out — or read the chart, which is all in the HTML.

  1. Type the number you are looking at

    Put the code into the lookup box — 418, or HTTP 429, or status: 502 pasted straight out of a log line, since any three digits in the input are treated as the code. The card gives the name, the RFC section that defines it today, what the code asserts and which neighbouring code you probably meant instead.

  2. Or search the chart by words

    Words go to the filter under the chart: type redirect, retry-after, webdav or 9110 and the rows that do not mention it disappear. The class buttons narrow to one hundred-range, and the cacheable tick-box reduces the chart to the 12 codes a shared cache may store with no freshness header at all.

  3. Check the code against its neighbour before you ship it

    Scroll to the thirteen comparisons under the chart, which are ordered by how often each mistake reaches code review: 301 against 308, 401 against 403, 400 against 422, 502 against 504. Each row names the situation, the code to send, the code people send instead, and the concrete consequence of getting it the wrong way round.

Technical specifications

Codes in the chart63 registered codes from 100 to 511, plus 16 vendor codes from nginx, Apache, IIS, AWS load balancers, Laravel and Cloudflare
Authority cited per rowThe document in force today, not the one that introduced the code — RFC 9110 (June 2022) absorbed RFC 7231 and RFC 7538, so 308 is cited as 9110 §15.4.9
Heuristically cacheable12 codes: 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501 — storable by a shared cache with no Cache-Control header present (RFC 9110 §15.1)
Must carry no body204, 205, 304 and every 1xx; a byte of payload after those headers is a framing error, not a cosmetic one
Codes with a mandatory companion header401 needs WWW-Authenticate, 405 needs Allow, 407 needs Proxy-Authenticate, 416 needs Content-Range, 426 needs Upgrade, 201 should carry Location and 429 and 503 should carry Retry-After
Reserved and unusable306, which was Switch Proxy in a 1998 draft, and 418, which RFC 9110 §15.5.19 pins down so the teapot joke can never be reassigned
RenderingEvery row is server-rendered HTML — the chart is complete with JavaScript disabled, and the search box, class buttons and lookup card are enhancements on top of it
Processing locationYour browser — the lookup runs against a table already in the page, so nothing you type is transmitted anywhere

Frequently asked questions

When should I use 307 instead of 302?

Use 307 whenever the request might not be a GET. A 307 obliges the client to repeat the original method and body at the new location, while 302 explicitly permits rewriting POST to GET — and every browser does, because that behaviour was so widespread by 1999 that RFC 2616 documented it as an erratum rather than fight it. So a POST to /checkout redirected with 302 arrives as a GET with no body, and the order vanishes. Pick 303 when you want the rewrite on purpose, 307 when the method must survive, and treat 302 as the code you inherited rather than the code you chose.

What is the difference between 401 and 403?

401 means the server does not know who you are; 403 means it knows and still says no. The name is the problem — 401 Unauthorized actually means unauthenticated, which is why it is the only 4xx status required to carry a WWW-Authenticate header naming the scheme the client should use. Retrying a 401 with a refreshed token is reasonable and a well-written client will do it automatically; retrying a 403 with the same identity is pointless, because the answer will not change until someone edits a permission. Where admitting the resource exists would itself leak something, returning 404 in place of 403 is a recognised and accepted practice.

Should a validation error be 400 or 422?

400 for bytes the parser rejected, 422 for a document that parsed and then failed your rules. Truncated JSON, a malformed header, a query string that is not valid percent-encoding: those are 400, because the request could not be understood. A well-formed body whose end date precedes its start date is 422 Unprocessable Content, which RFC 9110 promoted out of WebDAV into core HTTP in 2022 precisely so that API designers would stop apologising for it. Collapsing both into 400 costs the caller the one distinction that decides whether to fix the serialiser or fix the value.

Which status codes are cached by default?

Twelve of them: 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 and 501. RFC 9110 §15.1 calls these heuristically cacheable, meaning a shared cache is allowed to store and reuse the response even when you sent no Cache-Control and no Expires header. The two that catch people out are 404 and 301 — a mistyped route can stay missing behind a CDN long after the deploy that added it, and a 301 issued by accident is close to permanent because browsers cache it on disk. Send Cache-Control: no-store on error responses you expect to fix.

Which status codes are safe to retry automatically?

408, 425, 429, 500, 502, 503 and 504 — and only for idempotent methods. GET, HEAD, PUT and DELETE can be repeated without changing the outcome; POST cannot, unless you sent an idempotency key. 504 deserves particular care: the gateway gave up waiting, but the origin may have finished the work a second later, so a retried payment can charge twice. Honour Retry-After where the response carries one, and back off exponentially with jitter where it does not, because synchronised retries are how a recovering service is knocked over a second time.

What is the difference between 502, 503 and 504?

502 means the upstream answered with something invalid, 503 means the server is deliberately not serving, and 504 means the upstream never answered in time. Reading them as a chain saves debugging effort: 502 sends you to the origin's logs because the process probably crashed mid-response or closed the socket, 503 is usually your own maintenance flag or load-shedding rule and should always carry Retry-After, and 504 points at a slow query or a saturated upstream rather than at broken code. Cloudflare's 520 and 524 are the same two failures under vendor numbers.

Is 418 I'm a Teapot a real status code?

It is real, it is registered, and it is not usable. RFC 2324 defined it in the Hyper Text Coffee Pot Control Protocol as an April Fools' joke in 1998, RFC 7168 extended the protocol to teapots in 2014, and RFC 9110 §15.5.19 now lists 418 as reserved and permanently unassignable — the joke had become too well known for the number to be given to anything serious. Node.js, Go and Rust all ship the constant, so returning it works; it just means nothing to any client that receives it.

About HTTP status codes

The status line is the oldest surviving piece of HTTP’s design, and its cleverest constraint is that a client only has to understand the first digit. A cache written in 1996 that meets a 308 has never heard of it, reads the leading 3, and treats it as a redirect it cannot follow — which is exactly what the specification requires. That rule is why the registry could grow from the sixteen codes of HTTP/1.0 to the 63 listed here without breaking a single deployed client, and why inventing your own 4xx code is less reckless than it sounds, though the registry almost certainly already has the one you want.

The document to cite in 2026 is RFC 9110, published in June 2022, which consolidated RFC 7230 through 7235 and folded in scattered extensions: 308 arrived from RFC 7538, 422 was promoted out of WebDAV into core HTTP, and 413 was renamed from Payload Too Large to Content Too Large. Codes defined elsewhere kept their homes — 429 and 431 are still RFC 6585, 451 is RFC 7725, and the WebDAV block of 207, 423, 424 and 507 remains RFC 4918. Where a code is dormant the chart says so rather than pretending otherwise: 305 was deprecated as a security hazard, 306 is reserved and unassignable, and 510 has been marked obsolete since the HTTP Extension Framework it belonged to failed to ship.

Most status-code bugs are not exotic. They are a 200 wrapping an error object, which makes every dashboard downstream report a healthy service; a 302 where 307 was meant, which turns a POST into a GET and loses the body; or a 500 for a validation failure, which pages an on-call engineer at three in the morning for a caller’s typo. The comparison table above is the short version of that list. If you are checking what a server actually sent rather than what it should have, rebuild the request with the curl converter and watch the headers in your own client, and when a redirect chain is what you are untangling, put each Location value through the URL parser — a redirect loop is usually one query parameter growing by one hop.

What happens to what you type

Nothing leaves the page. The chart is already in the HTML your browser downloaded, and the lookup box searches that copy in memory — there is no query, no autocomplete request and no log of the code you were curious about.