Skip to content
DEV TOOL

HTTP Status Codes — Cloudflare, nginx, Snippets

RFC standard and platform codes in one tool — with confusion cards for the four most common traps and code snippets for six languages.

Static database in the browser — no API, no logging, no search sent to a server.

Search

Code number, reason phrase, or keyword. Examples: 404, "not found", "bad gateway".

Class

Coverage

HTTP method

Results

82 results

Details

404 Not Found RFC

The server cannot find the requested resource. Permanent disappearance should use 410 Gone; 404 means "not here, may or may not return". Servers may use 404 in place of 403 to hide whether a protected resource exists.

Typical HTTP methods

GETHEADPOSTPUTPATCHDELETE

Export code snippet

Includes ALL listed codes including platform codes. Six target languages.

// HTTP status codes — generated by kittokit http-status-lookup
export enum HttpStatus {
  /** The server has received the request headers and the client should proceed to send the request body. Used with the Expect: 100-continue header to let clients abort large uploads early when the server would have rejected them anyway. Most modern HTTP clients handle this transparently. */
  CONTINUE = 100,
  /** The server agrees to switch the application protocol of the connection in response to a client Upgrade header. The canonical use is the HTTP-to-WebSocket handshake. After 101 the connection is no longer HTTP — both peers speak the negotiated protocol. */
  SWITCHING_PROTOCOLS = 101,
  /** WebDAV interim response indicating the server has accepted a long-running request and is still working on it. Deprecated in practice — Servers should send 103 Early Hints instead. Originated in RFC 2518 and carried into RFC 4918. */
  PROCESSING = 102,
  /** Lets the server hint at resources the client should start fetching before the final response is ready. Typically used with Link: preload headers to warm up CSS, JS, fonts. Production-deployed by Chrome since 2022 and Cloudflare since 2021. */
  EARLY_HINTS = 103,
  /** Standard success response. The semantics depend on the HTTP method: GET returns the resource representation, HEAD returns just the headers, POST returns the result of the action, PUT/DELETE return the new state when no other 2xx is more specific. Body content is expected. */
  OK = 200,
  /** A new resource has been created as a result of the request. Typically returned by POST when a record is inserted or by PUT when a target URL did not previously exist. The Location header should point to the new resource. */
  CREATED = 201,
  /** The request has been queued for processing but is not yet complete. Used for asynchronous workflows — webhooks, video transcoding, batch jobs. The response body should describe how the client can check progress, often with a status-URL. */
  ACCEPTED = 202,
  /** The response was assembled by an intermediary — proxy, CDN, transforming gateway — and may differ from the origin server response. Rare in modern HTTP because proxies usually pass headers through unchanged. */
  NON_AUTHORITATIVE_INFORMATION = 203,
  /** The request succeeded and there is intentionally no response body. Common for POST, PUT, PATCH and DELETE when the client already knows the new state. Browsers will not navigate away from the current page on 204. */
  NO_CONTENT = 204,
  /** Tells the client to reset the form or UI view that initiated the request. Like 204 the response has no body. Rare in modern web apps because client-side state is reset in JavaScript. */
  RESET_CONTENT = 205,
  /** The server delivered a byte range of the resource because the client sent a Range header. Used by video players, download managers and HTTP-based file transfers to resume interrupted downloads. */
  PARTIAL_CONTENT = 206,
  /** WebDAV response that carries multiple status codes inside an XML body. Used when a single request touches multiple resources and each may succeed or fail independently — for example a PROPFIND on a collection. */
  MULTI_STATUS = 207,
  /** WebDAV binding extension marker. Used inside a 207 Multi-Status body to indicate that the same resource has already appeared earlier in the response and need not be repeated. */
  ALREADY_REPORTED = 208,
  /** Response from the HTTP Delta Encoding extension (RFC 3229). The server has applied an instance-manipulation to the resource. Almost never seen in modern HTTP — replaced by gzip/brotli at the transfer-encoding layer. */
  IM_USED = 226,
  /** The resource has multiple representations and the server wants the client to choose. The response body or Link headers describe the alternatives. Rare in practice — content-negotiation is usually handled with Accept headers and a single response. */
  MULTIPLE_CHOICES = 300,
  /** The resource has a new permanent URL given in the Location header. Search engines transfer ranking signals to the new URL. Historically clients converted POST to GET on 301 — use 308 for a strict method-preserving permanent redirect. */
  MOVED_PERMANENTLY = 301,
  /** Temporary redirect. The Location header gives the URL to use for this request only — the original URL stays canonical. Like 301, historical clients converted POST to GET on 302; use 307 to strictly preserve the method. */
  FOUND = 302,
  /** Tells the client to GET the resource at the Location URL — even if the original request used POST. The canonical Post-Redirect-Get pattern that prevents form re-submission on browser refresh. */
  SEE_OTHER = 303,
  /** Conditional-GET success — the client already has a current copy. Returned when If-None-Match or If-Modified-Since headers match the server-side resource. The client should reuse its cached representation. */
  NOT_MODIFIED = 304,
  /** Deprecated. The original intent was to tell the client to use a specific proxy. Implementations were inconsistent and the code was deprecated in RFC 7231. Modern servers should never emit it. */
  USE_PROXY = 305,
  /** Like 302 but the HTTP method must be preserved across the redirect. A POST stays a POST on the new URL. Use 307 instead of 302 for form-submission redirects where you do not want browsers to silently downgrade to GET. */
  TEMPORARY_REDIRECT = 307,
  /** Like 301 but the HTTP method must be preserved. The most modern of the four redirect codes — use 308 for permanent redirects where the method matters (PUT, POST, DELETE). Search engines treat it equivalent to 301 for ranking transfer. */
  PERMANENT_REDIRECT = 308,
  /** The request is malformed at the HTTP layer — invalid syntax, missing required headers, or framing errors. Not the right response for valid syntax with invalid business data: use 422 Unprocessable Content for that. */
  BAD_REQUEST = 400,
  /** Authentication is required and has either failed or not been provided. The response must include a WWW-Authenticate header. Despite the name the code means unauthenticated, not unauthorised — for authorisation failures use 403. */
  UNAUTHORIZED = 401,
  /** Reserved for future digital-payment use cases. Stripe and some SaaS APIs use 402 to signal a billing problem — overdue invoice, payment-method declined. No formal payment-handshake protocol is defined. */
  PAYMENT_REQUIRED = 402,
  /** The request is understood but the server refuses to authorise it. Authentication does not help — the user is known and still not allowed. Use 401 when credentials are missing or invalid, 403 when they are present but insufficient. */
  FORBIDDEN = 403,
  /** The server cannot find the requested resource. Permanent disappearance should use 410 Gone; 404 means "not here, may or may not return". Servers may use 404 in place of 403 to hide whether a protected resource exists. */
  NOT_FOUND = 404,
  /** The HTTP method is recognised but not allowed on this resource. The response must include an Allow header listing the supported methods, e.g. Allow: GET, POST. */
  METHOD_NOT_ALLOWED = 405,
  /** Content negotiation failed — the server has no representation that matches the client Accept headers. Rare in practice because most servers fall back to a default representation rather than refusing the request. */
  NOT_ACCEPTABLE = 406,
  /** Like 401 but the authentication challenge comes from a proxy on the path rather than the origin server. The response includes a Proxy-Authenticate header. Common with corporate proxies. */
  PROXY_AUTHENTICATION_REQUIRED = 407,
  /** The server closed an idle connection before the client finished sending the request. Browsers will often silently retry. Different from 504 Gateway Timeout — 408 is the server-to-client side waiting on data. */
  REQUEST_TIMEOUT = 408,
  /** The request conflicts with the current state of the resource. Typical examples: duplicate-key insert, optimistic-lock failure, edit collision in a version-controlled resource. The response body should explain how to resolve. */
  CONFLICT = 409,
  /** The resource used to exist but is permanently gone with no forwarding URL. Stronger and more search-engine-friendly than 404 for deliberately retired URLs — tells crawlers to drop the URL from their index. */
  GONE = 410,
  /** The server refuses to accept a request without a Content-Length header. Mostly relevant for legacy clients that send streaming PUT or POST without declaring body size. */
  LENGTH_REQUIRED = 411,
  /** A conditional header (If-Match, If-Unmodified-Since, If-None-Match for non-GET) did not match the current resource state. Used by clients that want to avoid overwriting concurrent edits — the ETag-based optimistic-lock pattern. */
  PRECONDITION_FAILED = 412,
  /** The request body is larger than the server is willing to process. Renamed from Payload Too Large in RFC 9110. Common with file-upload endpoints that enforce a max-body-size limit. */
  CONTENT_TOO_LARGE = 413,
  /** The request line — usually the URL itself — exceeds the server limit. Triggered by extremely long query strings or by GET requests that should have been POST. Typical limit on modern servers is 8 KB. */
  URI_TOO_LONG = 414,
  /** The request body Content-Type is not one the endpoint understands. Common when an API expects application/json and receives application/xml or form-urlencoded. */
  UNSUPPORTED_MEDIA_TYPE = 415,
  /** The client asked for a byte range that does not overlap the resource — for example bytes 500-999 of a 400-byte file. Typical reaction is to drop the Range header and reissue the GET. */
  RANGE_NOT_SATISFIABLE = 416,
  /** The server cannot meet the requirements of the Expect request header. The only widely-implemented expectation is Expect: 100-continue, which the server refuses with 417 if it never wants to receive the body. */
  EXPECTATION_FAILED = 417,
  /** The April Fools 1998 joke from RFC 2324 (Hyper Text Coffee Pot Control Protocol). Not part of HTTP proper but retained as a placeholder so the number is never reused. Some servers return it as an Easter egg. */
  I_M_A_TEAPOT = 418,
  /** The request was sent to a server that is not configured to produce a response for it. Typical with HTTP/2 connection coalescing when a connection serves multiple origins and one of them is wrong. */
  MISDIRECTED_REQUEST = 421,
  /** The request syntax is valid but the server cannot process the contained instructions — typically a business-rule or validation failure. Use 422 when 400 would be misleading because the HTTP framing is fine. */
  UNPROCESSABLE_CONTENT = 422,
  /** WebDAV. The resource is locked by another client and cannot be modified. Returned when a PUT/DELETE/MOVE collides with an active lock. */
  LOCKED = 423,
  /** WebDAV. A previous request the current one depended on has failed. Used inside Multi-Status responses to propagate failure between linked operations. */
  FAILED_DEPENDENCY = 424,
  /** The server refuses to process a request that was sent as TLS 1.3 early data because it would be vulnerable to replay attacks. The client should retry the request after the TLS handshake completes. */
  TOO_EARLY = 425,
  /** The server refuses to serve the request over the current protocol and indicates an upgrade is required. The Upgrade header lists acceptable protocols. Returned by HTTPS-only servers asked to talk plain HTTP/1.1. */
  UPGRADE_REQUIRED = 426,
  /** The server requires a conditional request to prevent the lost-update problem. Tells the client "send me an If-Match header on your next PUT". Used by APIs that enforce optimistic concurrency. */
  PRECONDITION_REQUIRED = 428,
  /** The client has exceeded a rate-limit. The Retry-After header tells the client how long to wait. Standard response for API throttling, brute-force protection and abuse mitigation. */
  TOO_MANY_REQUESTS = 429,
  /** The combined size of the request headers exceeds the server limit. Often caused by oversized Cookie headers — a few hundred small cookies accumulated across subdomains can trip an 8 KB header budget. */
  REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
  /** IIS-specific code. The client session has timed out and must reauthenticate. Common with Forms-Authentication-based ASP.NET applications behind IIS. */
  LOGIN_TIME_OUT = 440,
  /** nginx-internal code that signals the connection should be closed without sending any response headers. Used in configurations that silently drop malicious traffic — bot scanners, exploit probes. The client sees a reset connection rather than an error page. */
  NO_RESPONSE = 444,
  /** IIS-specific code. The server cannot process the request and asks the client to retry after performing an action — typically reauthentication. Largely obsolete in modern stacks. */
  RETRY_WITH = 449,
  /** The resource is blocked because of a legal demand — court order, takedown notice, geo-blocking. Number 451 references Fahrenheit 451. Use this instead of 403 when the refusal is a legal rather than authorisation matter. */
  UNAVAILABLE_FOR_LEGAL_REASONS = 451,
  /** AWS Elastic Load Balancer code. The client closed the connection before the idle-timeout elapsed, but the load balancer had already given up. Application-side equivalent of an nginx 499. */
  AWS_CLIENT_TIMEOUT = 460,
  /** AWS Application Load Balancer code. The X-Forwarded-For header carried more than 30 client-IP entries — usually a sign of a misconfigured forward-chain or a header-injection attempt. */
  AWS_X_FORWARDED_FOR_TOO_LARGE = 463,
  /** nginx-internal code. The client sent a request header that exceeded the large_client_header_buffers directive. nginx logs 494 even though the response on the wire is usually 400 Bad Request. */
  REQUEST_HEADER_TOO_LARGE = 494,
  /** nginx-internal code for client-certificate validation failures. The client presented a TLS certificate but it did not pass verification against the configured ssl_client_certificate. */
  SSL_CERTIFICATE_ERROR = 495,
  /** nginx-internal code. The endpoint requires a client certificate but the client did not present one. Mutual-TLS configurations log this when a client connects without identity material. */
  SSL_CERTIFICATE_REQUIRED = 496,
  /** nginx-internal code. The client opened a plain-HTTP connection on a port configured for HTTPS. Server-config can redirect with error_page 497 https://$host$request_uri to upgrade the request instead of erroring out. */
  HTTP_REQUEST_SENT_TO_HTTPS_PORT = 497,
  /** nginx-internal code. The client closed the connection before the server finished sending the response. Common with mobile apps that cancel an in-flight request when the user navigates away. */
  CLIENT_CLOSED_REQUEST = 499,
  /** A generic server-side failure. The server hit an unexpected condition and cannot complete the request. The catch-all code — frameworks and runtimes surface 500 for any unhandled exception. */
  INTERNAL_SERVER_ERROR = 500,
  /** The server does not support the functionality required to fulfil the request — typically because the HTTP method itself is unknown to the server. Use 405 when the method is known but disabled on this endpoint. */
  NOT_IMPLEMENTED = 501,
  /** The server, acting as a gateway or proxy, received an invalid response from an upstream server. Different from 504: 502 means the upstream replied with something broken, 504 means it never replied at all. */
  BAD_GATEWAY = 502,
  /** The server is temporarily unable to handle the request — overload, maintenance window, scheduled downtime. The Retry-After header may indicate when to try again. Different from 502 in that the server itself is the source of the failure. */
  SERVICE_UNAVAILABLE = 503,
  /** The gateway or proxy did not receive a timely response from the upstream server. Common on CDN edges when the origin takes longer to respond than the configured upstream-read-timeout (often 60–100 s). */
  GATEWAY_TIMEOUT = 504,
  /** The HTTP protocol version is not supported. Rare — modern servers accept HTTP/1.0, 1.1 and HTTP/2 universally, and very old or experimental versions are usually rejected at the parser layer instead. */
  HTTP_VERSION_NOT_SUPPORTED = 505,
  /** Internal misconfiguration in transparent content negotiation. The chosen variant is itself a negotiation result, creating an infinite loop. Theoretical — virtually never seen in production. */
  VARIANT_ALSO_NEGOTIATES = 506,
  /** WebDAV. The server cannot store the representation needed to complete the request — disk full, quota exceeded. Returned by file-storage APIs that enforce per-user limits. */
  INSUFFICIENT_STORAGE = 507,
  /** WebDAV binding extension. The server terminated an operation because it detected an infinite loop during processing — typically a circular reference in a directory tree. */
  LOOP_DETECTED = 508,
  /** Obsolete. RFC 2774 added an HTTP-extension framework; 510 was its protocol-level rejection. The extension framework never gained traction and the code is effectively retired. */
  NOT_EXTENDED = 510,
  /** A captive portal — typically a hotel or airport Wi-Fi splash page — intercepts the request and requires the client to authenticate to the network first. The response body should explain how. */
  NETWORK_AUTHENTICATION_REQUIRED = 511,
  /** Cloudflare reached the origin server but got back an empty, unknown or malformed response. Catch-all for upstream errors that do not fit any other 5xx code. Often points to a crashed origin worker or an HTTP framing problem. */
  WEB_SERVER_RETURNED_AN_UNKNOWN_ERROR = 520,
  /** Cloudflare cannot reach the origin server at all — the TCP connection is refused. Usually means the origin is offline, the firewall is blocking the Cloudflare IP ranges, or the listening port is wrong. */
  WEB_SERVER_IS_DOWN = 521,
  /** Cloudflare opened a TCP connection but the origin server did not complete the handshake in time. Typical causes: origin firewall dropping packets, origin overloaded, or routing problem between Cloudflare and the origin. */
  CONNECTION_TIMED_OUT = 522,
  /** Cloudflare cannot route to the origin server — DNS resolution failed, BGP route is missing, or the origin IP is invalid. Different from 521 because the connection attempt does not even reach the TCP layer. */
  ORIGIN_IS_UNREACHABLE = 523,
  /** Cloudflare opened a connection to the origin but it took longer than 100 seconds to start sending a response. Often a long-running database query or a slow API endpoint. Increase the origin response speed or use Cloudflare Workers to keep-alive the request. */
  A_TIMEOUT_OCCURRED = 524,
  /** The TLS handshake between Cloudflare and the origin failed. Causes include missing or mismatched origin certificates, unsupported cipher suites, or wrong SNI configuration in the Cloudflare SSL/TLS dashboard. */
  SSL_HANDSHAKE_FAILED = 525,
  /** Cloudflare could not validate the SSL certificate on the origin server when Full (strict) SSL mode is enabled. Self-signed or expired origin certificates trigger this. Either install a trusted cert or switch the mode to Full (without strict). */
  INVALID_SSL_CERTIFICATE = 526,
  /** The connection between Cloudflare and the Railgun listener at the origin failed. Railgun is the legacy origin-accelerator product and these errors usually point to a misconfigured rg-listener or firewall. */
  RAILGUN_ERROR = 527,
  /** A wrapper code that hides a deeper 1xxx error inside the Cloudflare error page. Open the response body and look for the inner code (1000 series) — it explains the actual problem, typically DNS misconfiguration on the orange-cloud origin. */
  ORIGIN_DNS_ERROR = 530,
  /** AWS CloudFront code emitted when an authentication add-on (Lambda@Edge) returns an unauthorised response and the viewer-request fails before reaching the origin. */
  AWS_UNAUTHORIZED = 561,
}

How It Works

  1. 01

    Paste text or code

    Paste your content into the input field or type directly.

  2. 02

    Instant processing

    The tool processes your content immediately and shows the result.

  3. 03

    Copy result

    Copy the result to your clipboard with one click.

Privacy

All calculations run directly in your browser. No data is sent to any server.

Not every HTTP status code is in MDN. Cloudflare 521, nginx 499, IIS 440 — platform codes go missing from many references, yet they show up in production logs. This tool lists both worlds: RFC 9110 plus Cloudflare 520-530, nginx 444/494-499, IIS 440/449, and AWS load-balancer codes. Search, filter, compare, export a snippet — all local in the browser.

01 — How to Use

How do you use this tool?

  1. Use the search box — code number, reason phrase, or keyword. Examples: 404, 'not found', 'bad gateway'.
  2. Class tabs (1xx-5xx) filter to one code family. The RFC / platform toggle hides one of the two worlds.
  3. Click a code in the list — the detail panel opens on the right with RFC + Wikipedia links and typical HTTP methods.
  4. For confusion codes (401 vs 403, 301/302/307/308, 400 vs 422, 502/503/504) a comparison card appears with click-through to the peers.
  5. The snippet block at the bottom emits the full list as TypeScript enum, Python dict, Go const, Rust enum, Java record, or Ruby module. Copy or download.

What does the HTTP status codes tool do?

The tool is a searchable reference catalogue for HTTP status codes. It covers RFC 9110 completely — every 1xx informational, 2xx success, 3xx redirection, 4xx client-error and 5xx server-error code — and adds the platform-specific codes that the IANA registry omits but that appear in your production log every day: Cloudflare 520-530, nginx 444 and 494-499, IIS 440 and 449, AWS Application Load Balancer 460/463, and CloudFront 561.

For each code the tool shows: the canonical reason phrase, a technical explanation in two to four sentences, the typical HTTP methods (POST tends to return 201, GET tends to return 200), a link to the specification (RFC, Cloudflare docs, nginx source), and a Wikipedia link for editorial context.

Which platform codes does the tool cover?

MDN documents only the IANA-registered standard. Tools that ship in your production stack regularly emit non-standard codes:

  • Cloudflare 520-527 and 530 — the full ‘edge could not reach the origin’ family. 521 (origin offline), 522 (connection timeout), 523 (origin DNS error), 524 (origin response > 100 s), 525 and 526 (origin SSL issues), 527 (Railgun error), 530 (wrapper for the 1xxx error series).
  • nginx 444 and 494-499 — internal codes from the nginx source: 444 (connection silently dropped), 494 (request header too large), 495 and 496 (client-certificate problems), 497 (HTTP request on HTTPS port), 499 (client closed the connection).
  • IIS 440 and 449 — Microsoft-specific codes: 440 (login timeout), 449 (Retry With).
  • AWS Application Load Balancer 460/463 and CloudFront 561 — cloud-provider edge codes for client timeout, oversized X-Forwarded-For chain, and Lambda@Edge auth failure.

The ‘platform codes only’ filter hides the RFC standard and shows only this world — useful when you look up a specific 5xx incident in the Cloudflare dashboard.

What are confusion cards?

Four code pairs are the most-confused in 2026 — the tool auto-shows a comparison card as soon as you select one of the codes:

  • 401 vs 403 — authentication (no login) vs authorisation (logged in but no permission).
  • 301 vs 302 vs 307 vs 308 — permanence × method preservation as a truth table. 308 = permanent + method preserving, the modern default.
  • 400 vs 422 — HTTP-layer error (syntax, framing) vs business-rule error (validation, conflict). Use 422 when the JSON is syntactically fine but the email field is invalid.
  • 502 vs 503 vs 504 — upstream broken vs origin overloaded vs upstream silent. The three gateway errors look similar but have different root-cause diagnoses.

Each cluster carries a one-to-two-sentence summary and buttons to the peer codes — click-through with no URL change.

How does the HTTP method filter work?

Every code in the database carries a list of ‘typical HTTP methods that produce this code’. The HTTP method filter narrows the list to one method: click ‘POST’ and you see only codes that make sense after a POST — 200, 201, 202, 204, 303, 307, 400, 409, 422, 429, 500. Click ‘GET’ and you see the GET-typical codes — 200, 206, 301, 304, 404, 410.

That is the inverse view of the detail card: there, each code says ‘these methods trigger me’; the filter says ‘this method returns me the following codes’.

Which snippet languages does the exporter support?

Six target languages, all generated client-side:

  • TypeScript enumexport enum HttpStatus { NOT_FOUND = 404, … } with JSDoc comments.
  • Python dictHTTP_STATUS_CODES = { 404: "Not Found", … } as a lookup map.
  • Go const blockconst ( StatusNot_Found = 404 … ) in idiomatic Go style.
  • Rust enum#[repr(u16)] pub enum HttpStatus { Not_Found = 404, … } with u16 representation.
  • Java recordpublic record HttpStatus(int code, String name) plus static final constants.
  • Ruby modulemodule HttpStatus NOT_FOUND = 404 … end as a constants container.

By default the exporter emits all codes — standard plus platform codes. You can narrow the selection with the ‘RFC standard only’ toggle; the platform world then disappears from the generated code. Both snippets are cleanly commented and can drop into a codebase as-is — no tests, no dependencies, no compiler warnings expected.

Why does this run pure-client without tracking?

This tool sends no request to a server. The whole status code database is embedded in the JavaScript bundle, search runs via String.prototype.toLowerCase and includes, snippet generation runs via template strings. No API calls, no telemetry, no cookies, no localStorage.

More in the OWASP Logging Cheat Sheet on what a tool search actually exposes — and why for security-relevant lookups (status-code research during an incident) it matters that the search does not end up in someone else’s log. The IANA HTTP Status Code Registry is the canonical source for IANA-registered codes; everything beyond that comes directly from platform documentation (Cloudflare 5xx errors, nginx HTTP request processing, Microsoft IIS HTTP status codes).

Last updated:

You might also like