HTTP Status Codes — Complete List with Meanings and Examples
Every official HTTP status code from 100 to 511, plus nginx, Cloudflare and AWS codes, with when to use each.
1xx Informational
100Continue
Interim response: the server has received the request headers and the client should go ahead and send the body.
Sent automatically by servers when a client includes "Expect: 100-continue" before uploading a large body, so the client does not waste bandwidth on a request that would be rejected.
Do not send it from application code as a final status; it is never the response to a request, only a step before the real one.
Not applicable
PUT /upload HTTP/1.1 Content-Length: 104857600 Expect: 100-continue HTTP/1.1 100 Continue
101Switching Protocols
The server agrees to switch the connection to the protocol named in the Upgrade header.
The handshake response for WebSocket connections (Upgrade: websocket) and, historically, HTTP/1.1 to h2c upgrades.
HTTP/2 and HTTP/3 do not use it; WebSockets over HTTP/2 use the extended CONNECT method (RFC 8441) instead.
Not applicable
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
102ProcessingDeprecated
Interim response telling the client the server is still working on a long WebDAV request, so it should not time out.
WebDAV. Removed from WebDAV in RFC 4918 but still in the IANA registry.
Only in legacy WebDAV servers handling slow recursive operations such as a deep COPY or MOVE.
New APIs should return 202 Accepted with a status URL for long-running work instead.
Not applicable
HTTP/1.1 102 Processing
103Early Hints
Interim response carrying Link headers so the browser can start preloading or preconnecting while the server is still preparing the final response.
When the HTML takes time to generate (server-side rendering, database queries) and you know which CSS, fonts or origins the page needs. Chromium browsers and Firefox act on preload and preconnect hints in 103 responses; Safari acts on preconnect.
Do not put headers in it that must only apply to the final response, such as Set-Cookie; browsers ignore most headers in 103.
Not applicable
HTTP/1.1 103 Early Hints Link: </style.css>; rel=preload; as=style Link: <https://cdn.example.com>; rel=preconnect HTTP/1.1 200 OK Content-Type: text/html
104Upload Resumption Supported
Interim response telling the client that the upload it has started can be resumed later, and where.
Temporary IANA registration for the IETF resumable uploads draft; not yet a final RFC.
Experimental: servers implementing the resumable uploads draft send it with a Location header for the upload resource.
Not for general use until the draft is published as an RFC; most clients and proxies do not know it.
Not applicable
draft-ietf-httpbis-resumable-upload
HTTP/1.1 104 Upload Resumption Supported Upload-Draft-Interop-Version: 6 Location: https://example.com/upload/b530ce8ff
2xx Success
200OKCacheable by default
The request succeeded. What the body contains depends on the method: the resource for GET, the result of the action for POST.
The normal success response for GET, and for POST, PUT, PATCH or DELETE when you return a body describing the result.
Do not return 200 with an error message in the body ("soft errors"). Clients, monitoring, caches and search engines read the status code, not your JSON.
Cacheable by default (heuristically cacheable)
HTTP/1.1 200 OK
Content-Type: application/json
{"id": 42, "name": "Ada"}201Created
The request succeeded and created one or more new resources.
After a POST (or a PUT to a new URL) that creates something. Include a Location header pointing to the new resource; the body usually describes it.
Do not use it when nothing new was created, for example an update to an existing record (use 200 or 204).
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 201 Created
Location: /users/42
Content-Type: application/json
{"id": 42}202Accepted
The request was accepted for processing, but processing has not finished and may still fail.
Queued or asynchronous work: video encoding, report generation, bulk imports. Return a link where the client can check the job status.
Do not use it to mean "success" for synchronous work; it explicitly promises nothing about the outcome.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 202 Accepted
Location: /jobs/7f3a
Content-Type: application/json
{"status": "queued"}203Non-Authoritative InformationCacheable by default
Success, but a transforming proxy has modified the origin server’s 200 response.
Only by intermediaries that change content, such as a proxy that compresses images or rewrites HTML, to tell the client it is not the origin’s exact response.
Origin servers and APIs should not send it.
Cacheable by default (heuristically cacheable)
HTTP/1.1 203 Non-Authoritative Information Content-Type: image/webp
204No ContentCacheable by default
Success, and there is intentionally no body.
DELETE that succeeded, PUT or PATCH when you do not return the updated resource, a form autosave, or a CORS preflight response.
Never include a body; clients will not read it, and on HTTP/1.1 a stray body corrupts the next response on the connection. Use 200 if you have something to return.
Cacheable by default (heuristically cacheable)
HTTP/1.1 204 No Content
205Reset Content
Success; the client should reset the document view, for example clear the form that was submitted.
Data-entry interfaces where the user submits a form and immediately enters another record.
Browsers do not implement the reset behaviour, so in practice it acts like 204. Must not include a body.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 205 Reset Content
206Partial ContentCacheable by default
The server is returning only the byte range(s) the client asked for with a Range header.
Video and audio seeking, resumable downloads and download managers that fetch a file in parallel chunks. Include Content-Range.
Do not send it unless the request had a Range header you are honouring. If you ignore Range, send 200 with the whole body.
Cacheable by default (heuristically cacheable)
GET /video.mp4 HTTP/1.1 Range: bytes=0-1023 HTTP/1.1 206 Partial Content Content-Range: bytes 0-1023/146515 Content-Length: 1024
207Multi-Status
The body (XML) contains a separate status for each of several resources.
WebDAV
WebDAV operations such as PROPFIND that act on many resources. Some JSON APIs borrow it for batch endpoints.
For batch APIs, many teams prefer 200 with per-item results, since generic clients treat 207 as plain success.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 207 Multi-Status Content-Type: application/xml; charset="utf-8"
208Already Reported
Used inside a 207 response to say a resource was already listed earlier, so it is not repeated (avoids loops with bindings).
WebDAV
WebDAV servers that support bindings (RFC 5842).
Not meaningful as a top-level response outside WebDAV.
Cacheable only with explicit Cache-Control or Expires
<D:status>HTTP/1.1 208 Already Reported</D:status>
226IM Used
The server fulfilled a GET with a delta (instance manipulation) applied to the current resource rather than the full resource.
Delta encoding for HTTP (A-IM / IM headers). Rarely deployed.
Not supported by browsers; do not use it in ordinary APIs.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 226 IM Used IM: vcdiff ETag: "v2"
3xx Redirection
300Multiple ChoicesCacheable by default
The resource has several representations and the client (or user) should pick one.
Rare: agent-driven content negotiation, for example offering a document in several languages or formats with links to each.
Browsers do not choose automatically. For language or format selection, server-driven negotiation or a normal page with links works better.
Cacheable by default (heuristically cacheable)
HTTP/1.1 300 Multiple Choices Link: </doc.en.html>; rel=alternate; hreflang=en Link: </doc.fr.html>; rel=alternate; hreflang=fr
301Moved PermanentlyCacheable by default
The resource has a new permanent URL, given in the Location header.
Domain moves, HTTP to HTTPS, changed slugs, consolidating duplicate URLs. Search engines transfer ranking signals to the new URL.
Browsers may change POST to GET when following a 301. If the method must be kept (an API endpoint that moved), use 308. Browsers cache 301s aggressively, so test before deploying.
Cacheable by default (heuristically cacheable)
HTTP/1.1 301 Moved Permanently Location: https://www.example.com/new-page
302Found
The resource is temporarily at a different URL; keep using the original URL in future.
Temporary redirects: login redirects, A/B tests, maintenance pages, geo or language redirects.
Browsers change POST to GET when following a 302 (historical behaviour the RFC allows). Use 303 for “go see the result” after a POST, and 307 when the method must be preserved.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 302 Found Location: /login?next=%2Faccount
303See Other
Redirect the client to another URL, which it must fetch with GET.
The Post/Redirect/Get pattern: after a form POST, send 303 to the result page so a page refresh does not resubmit the form.
Not for moved content; it says nothing about the original URL having moved.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 303 See Other Location: /orders/1234
304Not Modified
Response to a conditional GET or HEAD (If-None-Match or If-Modified-Since): the client’s cached copy is still valid.
Cache revalidation: not stored itself, but it refreshes the cached response the client already holds.
Automatically by servers and CDNs when the ETag or Last-Modified date matches, saving the transfer of an unchanged body.
Never send a body. Do not send it to a request that was not conditional; the client has nothing to reuse.
Not applicable
GET /app.js HTTP/1.1 If-None-Match: "33a64df5" HTTP/1.1 304 Not Modified ETag: "33a64df5" Cache-Control: max-age=3600
305Use ProxyDeprecated
Deprecated. Once told the client to repeat the request through a proxy named in Location.
Nothing. It was deprecated for security reasons and browsers ignore it.
Do not send it.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 305 Use Proxy
306(Unused)Deprecated
Reserved. It was used in a draft for "Switch Proxy" and is no longer used.
Nothing.
Do not send it.
Not applicable
307Temporary Redirect
Temporary redirect where the client must repeat the request with the same method and body.
Temporarily redirecting POST, PUT or DELETE requests (an API endpoint moved for maintenance). Browsers also show an internal 307 when HSTS forces HTTPS.
For a permanent move, use 308. For "go fetch the result with GET", use 303.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 307 Temporary Redirect Location: https://api2.example.com/v1/orders
308Permanent RedirectCacheable by default
Permanent redirect where the client must repeat the request with the same method and body.
A permanently moved API endpoint that receives POST or PUT. Search engines treat it like 301. Next.js and Vercel use 308 for permanent redirects by default.
Very old clients (Internet Explorer on Windows 7 and earlier) do not understand it; for plain page moves 301 is equally good.
Cacheable by default (heuristically cacheable)
HTTP/1.1 308 Permanent Redirect Location: https://example.com/api/v2/upload
4xx Client error
400Bad Request
The server will not process the request because of a client error: malformed syntax, invalid framing or invalid parameters.
Unparseable JSON, a missing required parameter, a value of the wrong type. Explain the problem in the body (RFC 9457 problem+json is a good format).
For well-formed input that fails business rules, many APIs use 422. For authentication problems use 401 or 403.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{"title": "Invalid JSON", "detail": "Unexpected token } at position 41"}401Unauthorized
The request lacks valid authentication credentials. Despite the name, it means "unauthenticated".
No token, an expired token or a wrong password. The response must include a WWW-Authenticate header describing how to authenticate.
If the user is logged in but not allowed, use 403. Do not send 401 without WWW-Authenticate.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="api", error="invalid_token"
402Payment Required
Reserved for future use. There is no standard semantics.
Some APIs use it for "quota exhausted, upgrade your plan" or a failed payment (Stripe returns 402 for declined card requests).
Do not rely on clients understanding it; describe the problem in the body.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 402 Payment Required
Content-Type: application/json
{"error": "card_declined"}403Forbidden
The server understood the request and knows who you are (or does not care) but refuses to fulfil it.
The authenticated user lacks permission, an IP is blocked, directory listing is disabled, or a WAF rule fired. Re-authenticating will not help.
If credentials are missing or invalid, use 401. If revealing that the resource exists is itself a leak, return 404 instead.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 403 Forbidden
Content-Type: application/json
{"error": "You do not have access to this project"}404Not FoundCacheable by default
The server has no current representation for the URL, or will not say whether one exists.
Unknown URLs, deleted records when you do not track deletions, or hiding resources from unauthorised users.
If the resource existed and is gone for good, 410 states that explicitly. Do not return a 200 page that says "not found" (a soft 404).
Cacheable by default (heuristically cacheable)
HTTP/1.1 404 Not Found Content-Type: text/html
405Method Not AllowedCacheable by default
The URL exists, but does not support this HTTP method.
A DELETE to a read-only resource or a POST to a GET-only page. The response must include an Allow header listing the supported methods.
Do not use it for permission problems (403) or for methods the server does not implement at all (501).
Cacheable by default (heuristically cacheable)
HTTP/1.1 405 Method Not Allowed Allow: GET, HEAD
406Not Acceptable
The server cannot produce a response matching the request’s Accept, Accept-Language or Accept-Encoding headers.
An API that only speaks JSON receiving "Accept: application/xml" with no fallback.
Most servers ignore unmatched Accept headers and send their default format instead, which is usually friendlier.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
{"supported": ["application/json"]}407Proxy Authentication Required
Like 401, but the client must authenticate with the proxy in between.
Sent by forward proxies (corporate proxies), with a Proxy-Authenticate header.
Origin servers should never send it.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 407 Proxy Authentication Required Proxy-Authenticate: Basic realm="corp-proxy"
408Request Timeout
The server did not receive a complete request in the time it was prepared to wait, and is closing the connection.
Sent by servers on idle keep-alive connections or slow uploads. Clients may retry the request on a new connection.
Not for slow back-end processing; that is a 504 at a gateway or simply a slow response. Send "Connection: close" with it.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 408 Request Timeout Connection: close
409Conflict
The request conflicts with the current state of the resource.
Creating a user whose email already exists, editing a record someone else changed (version mismatch), deleting a non-empty folder.
For failed If-Match / If-Unmodified-Since conditions, use 412. For validation errors, use 400 or 422.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error": "Email already registered"}410GoneCacheable by default
The resource used to exist here, is gone permanently, and has no forwarding address.
Discontinued products, expired promotions, deleted accounts, retired API versions. Google treats 404 and 410 almost the same, though a 410 may be dropped from the index a little sooner.
If the content moved, redirect with 301 instead. If you are not sure it is permanent, use 404.
Cacheable by default (heuristically cacheable)
HTTP/1.1 410 Gone
411Length Required
The server requires a Content-Length header on this request.
Servers that refuse chunked uploads and need to know the body size in advance.
Rarely needed by applications; usually emitted by the web server itself.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 411 Length Required
412Precondition Failed
A condition in the request headers (If-Match, If-Unmodified-Since, If-None-Match on a write) evaluated to false.
Optimistic concurrency: the client sent If-Match with an old ETag, meaning someone else changed the resource first.
Do not use it for business-rule failures that have nothing to do with conditional headers (409 or 422).
Cacheable only with explicit Cache-Control or Expires
PUT /docs/7 HTTP/1.1 If-Match: "v3" HTTP/1.1 412 Precondition Failed ETag: "v4"
413Content Too Large
The request body is larger than the server is willing to process. Called "Payload Too Large" before RFC 9110.
Uploads over the limit (nginx client_max_body_size, a 10 MB API cap). If the limit is temporary, add Retry-After.
For a URL that is too long use 414; for too-large headers use 431.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 413 Content Too Large Connection: close
414URI Too LongCacheable by default
The request target (URL) is longer than the server will interpret.
Huge query strings, often a GET form that should be a POST, or a redirect loop that keeps appending parameters.
Move large inputs to a request body (POST) rather than raising the limit indefinitely.
Cacheable by default (heuristically cacheable)
HTTP/1.1 414 URI Too Long
415Unsupported Media Type
The server refuses the request because the body’s format (Content-Type or Content-Encoding) is not supported.
An endpoint that accepts JSON receiving form data or XML, or a missing Content-Type header. Include Accept-Post or Accept-Patch to show what is supported.
Not for a body in the right format with invalid content (400 or 422).
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 415 Unsupported Media Type Accept-Post: application/json
416Range Not Satisfiable
None of the byte ranges in the Range header overlap the resource, for example asking for bytes beyond the end of the file.
Resumed downloads where the file has shrunk or the client asks past its end. Include Content-Range: bytes */<length>.
Servers may simply ignore an invalid Range and return 200 with the full body, which is also allowed.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 416 Range Not Satisfiable Content-Range: bytes */47022
417Expectation Failed
The server cannot meet the requirement in the request’s Expect header.
A client sent "Expect: 100-continue" to a server or proxy that does not support it, or an unknown expectation.
Clients that get it should retry without the Expect header.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 417 Expectation Failed
418(Unused)
Reserved by RFC 9110 because 418 was widely deployed as the “I’m a teapot” joke code; it has no defined meaning in HTTP.
Reserved. Famous as “I’m a teapot” from the 1998 April Fools’ RFC 2324 (HTCPCP).
Only as an Easter egg. Some services use it to answer requests they want to reject in a humorous way.
Do not use it for real errors; it cannot be assigned a meaning and clients will not know what to do.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 418 I'm a teapot
419Page ExpiredUnofficial · Laravel
Laravel returns it when the CSRF token is missing or has expired, usually after a session timed out on a page with a form.
Sent by Laravel’s CSRF middleware. Fix by refreshing the page, including @csrf in forms, or sending the X-CSRF-TOKEN header with AJAX requests.
Not a standard code; do not send it from non-Laravel APIs.
Not applicable
Laravel (not in the IANA registry)
HTTP/1.1 419 unknown status
420Enhance Your CalmUnofficial · Twitter (legacy)
The old Twitter API’s rate-limit response, replaced by the standard 429.
Nothing new. You may still meet it in old client libraries. Spring once defined 420 "Method Failure", now deprecated.
Use 429 for rate limiting.
Not applicable
Twitter API v1 (not in the IANA registry)
HTTP/1.1 420 Enhance Your Calm
421Misdirected Request
The request reached a server that cannot produce a response for that host and scheme.
HTTP/2 connection coalescing went wrong: the browser reused a connection for another hostname covered by the same certificate, but the server does not serve it. The client should retry on a new connection.
Not for ordinary unknown hostnames on a single server; that is usually a 404 or the default virtual host.
Cacheable only with explicit Cache-Control or Expires
HTTP/2 421
422Unprocessable Content
The request is well-formed and in a supported format, but its content fails validation. Called "Unprocessable Entity" in RFC 4918.
Form and API validation errors: an email that is not an email, an end date before the start date. Rails, Laravel and FastAPI use it by default.
For malformed syntax (unparseable JSON) use 400.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json
{"errors": {"email": ["is invalid"]}}423Locked
The resource is locked, so the request cannot change it.
WebDAV
WebDAV LOCK semantics. Some APIs use it for records being edited by someone else or accounts locked after failed logins.
Outside WebDAV, 409 is better understood by generic clients.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 423 Locked
424Failed Dependency
The action failed because another action it depended on failed.
WebDAV
In a WebDAV PROPPATCH or a batch request, items that were not attempted because an earlier item failed.
Not for upstream service failures; those are 502 or 503.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 424 Failed Dependency
425Too Early
The server will not process a request sent in TLS 1.3 early data (0-RTT) because it might be replayed.
CDNs and servers that accept 0-RTT but reject non-idempotent requests (POST) in early data. The client retries after the handshake completes.
Not a general "try later" code; use 503 with Retry-After for that.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 425 Too Early
426Upgrade Required
The server refuses the request on the current protocol but would accept it after an upgrade named in the Upgrade header.
Requiring TLS or a newer protocol, or a WebSocket endpoint hit with a plain HTTP request. Must include an Upgrade header.
For HTTP to HTTPS on websites, a 301 or 308 redirect plus HSTS is the usual approach.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 426 Upgrade Required Upgrade: TLS/1.3, HTTP/1.1 Connection: Upgrade
428Precondition Required
The server requires the request to be conditional (If-Match etc.), to prevent lost updates.
APIs that insist clients send If-Match with the ETag they last saw before a PUT, PATCH or DELETE.
Use 412 when a precondition was sent and failed; 428 is for when none was sent.
Must not be stored by caches
HTTP/1.1 428 Precondition Required
Content-Type: application/json
{"error": "Send If-Match with the current ETag"}429Too Many Requests
The client sent too many requests in a given time (rate limiting).
API rate limits, login throttling, scraping protection. Include Retry-After so well-behaved clients know when to come back; RateLimit headers help too.
For a server that is overloaded for everyone, use 503. Googlebot treats 429 like 503 and slows down crawling.
Must not be stored by caches
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{"error": "Rate limit exceeded: 100 requests per minute"}431Request Header Fields Too Large
The headers, individually or together, are too large for the server.
Usually oversized cookies accumulated on a domain, or huge Authorization tokens. Clearing cookies often fixes it for users.
For a long URL use 414; for a large body use 413.
Must not be stored by caches
HTTP/1.1 431 Request Header Fields Too Large
440Login Time-outUnofficial · Microsoft IIS / Exchange
The client’s session expired and it must log in again (Outlook Web Access and other IIS apps).
Seen in Exchange/OWA environments.
Use 401 for expired sessions in your own apps.
Not applicable
Microsoft IIS (not in the IANA registry)
HTTP/1.1 440 Login Time-out
444No ResponseUnofficial · nginx
nginx-internal code: "return 444;" closes the connection without sending any response at all.
Dropping requests from scanners, requests for unknown Host headers in a default server block, or abusive clients. It appears in nginx logs; the client sees an empty reply.
The client never receives a 444, so it is not something to handle in client code.
Not applicable
nginx (not in the IANA registry)
server {
listen 80 default_server;
return 444;
}449Retry WithUnofficial · Microsoft
Microsoft extension: the request should be retried after the client performs a specific action.
Seen in some Microsoft services (Exchange ActiveSync, Azure Cosmos DB uses 449 for retryable write conflicts).
Not standard; use 409 or 503 with Retry-After in your own APIs.
Not applicable
Microsoft IIS (not in the IANA registry)
HTTP/1.1 449 Retry With
450Blocked by Windows Parental ControlsUnofficial · Microsoft
Windows Parental Controls blocked access to the page.
Generated on Windows systems with parental controls.
Do not send it from servers.
Not applicable
Microsoft (not in the IANA registry)
HTTP/1.1 450 Blocked by Windows Parental Controls
451Unavailable For Legal ReasonsCacheable by default
Access is denied because of a legal demand: a court order, government censorship or a geo-restriction for legal reasons.
Content blocked in a jurisdiction (sanctions, GDPR-related geo-blocks, takedown orders). A Link header with rel="blocked-by" can name who imposed it.
Not for ordinary permission denials (403) or for content you simply chose to remove (410).
Cacheable by default (heuristically cacheable)
HTTP/1.1 451 Unavailable For Legal Reasons Link: <https://authority.example/>; rel="blocked-by"
460Client closed connection (AWS ELB)Unofficial · AWS Application Load Balancer
Logged by an AWS ALB when the client closed the connection before the idle timeout elapsed.
Seen in ALB access logs; usually a client with a shorter timeout than the target’s processing time.
Not sent to clients.
Not applicable
AWS Elastic Load Balancing (not in the IANA registry)
elb_status_code=460
463Too many IPs in X-Forwarded-For (AWS ELB)Unofficial · AWS Application Load Balancer
The ALB received an X-Forwarded-For header with more than 30 IP addresses.
Usually a proxy loop that keeps appending addresses.
Not for application use.
Not applicable
AWS Elastic Load Balancing (not in the IANA registry)
HTTP/1.1 463
494Request Header Too LargeUnofficial · nginx
nginx-internal code for headers exceeding large_client_header_buffers; the client receives a 400.
Appears in nginx logs and error_page configuration.
The standard code is 431.
Not applicable
nginx (not in the IANA registry)
error_page 494 /header-too-large.html;
495SSL Certificate ErrorUnofficial · nginx
nginx-internal: the client presented an invalid client certificate (mutual TLS). Sent to the client as 400.
Custom error pages for mTLS failures.
Not a wire status code.
Not applicable
nginx (not in the IANA registry)
error_page 495 /bad-client-cert.html;
496SSL Certificate RequiredUnofficial · nginx
nginx-internal: a client certificate was required but not provided. Sent to the client as 400.
Custom error pages when ssl_verify_client is on.
Not a wire status code.
Not applicable
nginx (not in the IANA registry)
error_page 496 /client-cert-required.html;
497HTTP Request Sent to HTTPS PortUnofficial · nginx
nginx-internal: a plain HTTP request arrived on a port that expects TLS. Sent to the client as 400.
A common trick is "error_page 497 =301 https://$host$request_uri;" to redirect such requests to HTTPS.
Not a wire status code.
Not applicable
nginx (not in the IANA registry)
error_page 497 =301 https://$host:$server_port$request_uri;
498Invalid TokenUnofficial · Esri ArcGIS Server
ArcGIS returns it for an expired or otherwise invalid token.
Only relevant when calling ArcGIS services.
Use 401 for invalid tokens in your own APIs.
Not applicable
Esri ArcGIS (not in the IANA registry)
HTTP/1.1 498 Invalid Token
499Client Closed RequestUnofficial · nginx
nginx logs 499 when the client closed the connection before nginx sent a response.
Seen in access logs: users navigating away, mobile clients timing out, or a load balancer in front of nginx with a shorter timeout. Many 499s on one endpoint usually mean it is too slow.
The client never receives it. Esri also uses 499 for "Token Required".
Not applicable
nginx (not in the IANA registry)
203.0.113.9 - - [16/Oct/2026:10:12:01 +0000] "GET /report HTTP/1.1" 499 0
5xx Server error
500Internal Server Error
The server hit an unexpected condition that stopped it from fulfilling the request.
Unhandled exceptions and bugs. It is the generic fallback when no more specific 5xx applies.
Do not use it for client mistakes (4xx). Do not leak stack traces in the body in production; log them instead.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 500 Internal Server Error
Content-Type: application/problem+json
{"title": "Internal Server Error", "traceId": "4bf92f35"}501Not ImplementedCacheable by default
The server does not support the functionality required, typically an HTTP method it does not recognise at all.
A request with an unknown method (e.g. a WebDAV method on a plain web server), or a feature the server has deliberately not built yet.
If the method is known but not allowed on this URL, use 405.
Cacheable by default (heuristically cacheable)
HTTP/1.1 501 Not Implemented
502Bad Gateway
A gateway or proxy got an invalid response from the upstream server.
Sent by reverse proxies and load balancers (nginx, Cloudflare, AWS ALB) when the app server crashed, closed the connection or returned garbage.
Application code rarely needs to send it, except API gateways that call another service which failed.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 502 Bad Gateway Server: nginx
503Service Unavailable
The server cannot handle the request right now: overloaded, or down for maintenance. Expected to be temporary.
Planned maintenance, load shedding, a dependency outage. Add Retry-After. Search engines keep the page indexed during short 503 periods, unlike a 200 maintenance page or 404.
Do not leave a site on 503 for days; Google eventually drops URLs that keep returning it.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 503 Service Unavailable Retry-After: 3600
504Gateway Timeout
A gateway or proxy did not get a response from the upstream server in time.
Sent by proxies and load balancers when the application takes longer than the proxy timeout (nginx proxy_read_timeout defaults to 60 seconds).
For long jobs, do not just raise timeouts; return 202 and process asynchronously.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 504 Gateway Timeout Server: awselb/2.0
505HTTP Version Not Supported
The server does not support the major HTTP version used in the request.
A server receiving a protocol version it cannot speak.
Rarely seen; clients negotiate HTTP/2 and HTTP/3 through ALPN and Alt-Svc rather than by trial.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 505 HTTP Version Not Supported
506Variant Also Negotiates
Server configuration error: the chosen variant is itself set up to negotiate, creating a loop.
Transparent content negotiation (experimental)
Only servers implementing RFC 2295 transparent content negotiation.
Not for application errors.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 506 Variant Also Negotiates
507Insufficient Storage
The server cannot store what is needed to complete the request.
WebDAV
WebDAV or file-storage APIs when the disk or the user’s quota is full.
For a single upload that exceeds a size limit, 413 is clearer.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 507 Insufficient Storage
508Loop Detected
The server stopped an operation because it found an infinite loop (WebDAV bindings with Depth: infinity).
WebDAV
WebDAV servers. CloudLinux-based shared hosts also send 508 "Resource Limit Is Reached" when an account hits its limits, which is non-standard.
Not for redirect loops; those are a client-side error the browser reports itself.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 508 Loop Detected
509Bandwidth Limit ExceededUnofficial · Apache bw_mod / cPanel
The hosting account has exceeded its bandwidth allowance.
Shared hosting control panels.
Use 503 or 429 in your own systems.
Not applicable
Apache / cPanel (not in the IANA registry)
HTTP/1.1 509 Bandwidth Limit Exceeded
510Not ExtendedDeprecated
The request did not meet the policy for accessing the resource under the HTTP Extension Framework.
Marked obsoleted in the IANA registry: RFC 2774 was moved to Historic.
Nothing current; the extension framework was never widely implemented.
Do not send it.
Cacheable only with explicit Cache-Control or Expires
HTTP/1.1 510 Not Extended
511Network Authentication Required
The client must authenticate to gain network access: a captive portal.
Hotel, airport and café Wi-Fi portals intercepting traffic until the user logs in or accepts terms.
Origin servers must never send it; it is for intercepting network proxies only.
Must not be stored by caches
HTTP/1.1 511 Network Authentication Required Content-Type: text/html <meta http-equiv="refresh" content="0; url=https://login.example.net/">
520Web Server Returned an Unknown ErrorUnofficial · Cloudflare
The origin returned an empty, unknown or unexpected response to Cloudflare.
Check origin logs: crashes, connection resets, headers over Cloudflare’s limit, or an empty reply.
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 520 server: cloudflare
521Web Server Is DownUnofficial · Cloudflare
Cloudflare could not connect to the origin: the connection was refused.
The origin web server is stopped, or a firewall is blocking Cloudflare’s IP ranges.
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 521 server: cloudflare
522Connection Timed OutUnofficial · Cloudflare
Cloudflare timed out establishing a TCP connection to the origin.
Origin overloaded, packets dropped by a firewall, or a wrong origin IP in DNS.
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 522 server: cloudflare
523Origin Is UnreachableUnofficial · Cloudflare
Cloudflare cannot reach the origin at all, typically a routing problem or wrong DNS record.
Check that the DNS A/AAAA records point at the right, reachable IP.
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 523 server: cloudflare
524A Timeout OccurredUnofficial · Cloudflare
Cloudflare connected to the origin, but the origin did not send an HTTP response within the timeout (100 seconds by default).
Long-running requests: move the work to a background job and poll, or stream progress.
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 524 server: cloudflare
525SSL Handshake FailedUnofficial · Cloudflare
The TLS handshake between Cloudflare and the origin failed.
Origin not listening on 443, no certificate, no shared cipher suites, or SNI not configured, while the SSL mode is Full or Full (strict).
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 525 server: cloudflare
526Invalid SSL CertificateUnofficial · Cloudflare
In Full (strict) mode, Cloudflare could not validate the origin’s certificate: expired, self-signed, or wrong hostname.
Install a valid certificate or a Cloudflare Origin CA certificate on the origin.
Only Cloudflare sends it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 526 server: cloudflare
527Railgun ErrorUnofficial · Cloudflare (retired)Deprecated
Connection problem between Cloudflare and a Railgun listener at the origin. Cloudflare has discontinued Railgun.
Historical only.
Only Cloudflare sent it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/1.1 527 Railgun Error
530Origin DNS / 1xxx errorUnofficial · Cloudflare
Returned with a Cloudflare 1xxx error page (such as 1016 Origin DNS error); the 1xxx code shown on the page is the real cause.
Look up the 1xxx error number shown on the page.
Only CDNs and hosts send it.
Not applicable
Cloudflare (not in the IANA registry)
HTTP/2 530 server: cloudflare
561Unauthorized (AWS ELB)Unofficial · AWS Application Load Balancer
The ALB’s built-in authentication (OIDC or Cognito) failed with the identity provider.
Check the IdP configuration of the ALB listener rule.
Not for application use.
Not applicable
AWS Elastic Load Balancing (not in the IANA registry)
HTTP/1.1 561
598Network Read Timeout ErrorUnofficial · Some HTTP proxies
Used by some proxies to signal a read timeout behind the proxy.
Rare; you may see it from certain proxy products.
Use 504.
Not applicable
Informal convention (not in the IANA registry)
HTTP/1.1 598
599Network Connect Timeout ErrorUnofficial · Some HTTP proxies and clients
Used by some proxies and client libraries (Tornado’s HTTP client, for example) for a connection timeout.
Rare.
Use 504 for proxies.
Not applicable
Informal convention (not in the IANA registry)
HTTP/1.1 599
A static reference that runs in your browser; your searches are not sent anywhere. Browse all free tools.
Found a problem, or something that could be better? We read every message and we fix things quickly.
This HTTP status code list covers every code in the IANA registry, from 100 Continue to 511 Network Authentication Required, with the meaning, when to use it, when not to, whether caches may store it, and the RFC section that defines it. Type a number, a class such as 4xx, or a word such as “redirect” or “rate limit” to filter, and link straight to any code with an anchor such as #404 or #503.
The official entries follow RFC 9110 (2022), which replaced RFC 7231 and renamed a few codes: 413 is now Content Too Large and 422 is Unprocessable Content. Codes you see in logs but will not find in the registry, such as nginx 499 or Cloudflare 522, are included too and marked unofficial, with the system that sends them. It is a reference, not a monitor: it does not fetch URLs or check what status a live site returns.
How to use
- Type a code (503), a class (4xx) or a keyword (timeout, redirect, cache) into the search box. Results filter as you type.
- Use the class buttons to see only 1xx, 2xx, 3xx, 4xx or 5xx codes, and untick “Include unofficial codes” to hide vendor-specific ones.
- Click a code to expand it: meaning, when to use it, when not to, caching behaviour, the defining RFC and an example response.
- Use “Copy link to this code” to share a direct link such as /tools/http-status-codes#429.
Frequently asked questions
What is the difference between 401 and 403?
401 Unauthorized means the request has no valid credentials: the client is not logged in, or the token expired. The server must send a WWW-Authenticate header saying how to authenticate. 403 Forbidden means the server knows who the client is, or does not need to, and still refuses; logging in again will not help. In short, 401 is “who are you?” and 403 is “I know, and no.”
Should I use 301 or 308 for a permanent redirect?
Both are permanent and both pass ranking signals in Google. The difference is the method: when following a 301, browsers may turn a POST into a GET, while 308 requires the client to repeat the same method and body. For ordinary page moves 301 is fine; for an API endpoint that receives POST or PUT, use 308. The same pairing exists for temporary redirects: 302 may change the method, 307 must not.
What does 499 mean in nginx logs?
499 Client Closed Request is an nginx-only code. It is logged when the client closed the connection before nginx sent a response, so the client never actually receives a 499. Occasional 499s are users navigating away; many on one endpoint usually mean it is too slow and clients or an upstream load balancer are timing out first.
What is the difference between 502, 503 and 504?
All three come from a server that sits in front of another one. 502 Bad Gateway means the proxy got an invalid response or a dropped connection from the upstream app. 503 Service Unavailable means the server is temporarily unable to handle requests, usually overload or maintenance, and should include Retry-After. 504 Gateway Timeout means the proxy gave up waiting for the upstream to answer.
Is 418 I'm a teapot a real status code?
It started as an April Fools’ joke in RFC 2324 (1998) and was implemented by enough software that RFC 9110 now lists 418 as “(Unused)”: reserved so it is never given a real meaning. It is not an error you should send for real problems, but it is safe to keep in an Easter egg.
Which status codes can be cached by default?
RFC 9110 names 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 and 501 as heuristically cacheable, which means a cache may store them even without Cache-Control or Expires. RFC 7725 adds 451. Other codes, including 302 and 307, are cached only when the response carries explicit freshness information, and RFC 6585 says 428, 429, 431 and 511 must not be stored at all.
The five classes at a glance
• 1xx Informational: interim responses before the final one. You rarely handle them directly; 101 (WebSocket upgrade) and 103 (Early Hints) are the ones that matter in practice.
• 2xx Success: the request worked. 200 for a normal response, 201 when something was created (with a Location header), 204 when there is deliberately no body.
• 3xx Redirection: the client must look elsewhere. 301/308 for permanent moves, 302/307 for temporary ones, 303 after a form POST, 304 when the cached copy is still valid.
• 4xx Client error: the request is wrong and repeating it unchanged will fail again. 400 malformed, 401 not authenticated, 403 not allowed, 404 not found, 409 conflict, 422 failed validation, 429 rate limited.
• 5xx Server error: the request may be fine but the server failed. 500 is a bug, 502/504 are proxy-to-upstream failures, 503 is temporary unavailability.
Choosing the right code in an API
Return the most specific code a generic client can act on, and put the detail in the body. A retrying HTTP client, a CDN or a monitoring system knows what 429 and 503 mean without reading your JSON, but it cannot interpret a 200 with {"error": true}. RFC 9457 (Problem Details) gives a standard JSON shape for error bodies.
A practical mapping for most JSON APIs: 400 for unparseable input, 422 for well-formed input that fails validation, 401 when the token is missing or expired, 403 when the user lacks permission, 404 for unknown IDs (also to hide resources a user may not see), 409 for duplicates and version conflicts, 412 when an If-Match ETag is stale, 429 with Retry-After for rate limits, and 503 with Retry-After for planned downtime.
Do not invent new numbers. Clients treat an unknown code as the x00 of its class (an unknown 4xx is handled like 400), so a custom 461 gains you nothing over 400 plus a clear message.
Status codes and SEO
Search engines read status codes literally. A 301 or 308 transfers the old URL’s signals to the new one; a 302 or 307 tells Google to keep the old URL indexed. 404 and 410 both remove a page from the index over time. A 200 page that says “not found” is a soft 404, which Google detects and reports in Search Console. For maintenance, a short period of 503 with Retry-After keeps rankings intact, while a 200 “we’ll be back” page can replace your content in search results. Googlebot also slows its crawl rate when it sees 429, 500 or 503.
Related free tools
- User Agent Parser — See your own user agent and client hints, or parse any UA string into browser, engine, OS, device and CPU. Bulk mode with CSV.
- JSON Formatter — Pretty-print, minify and validate JSON, with parse errors located by line and column. In your browser, no upload.
- Docker Run ⇄ Compose — Turn a docker run command into a docker-compose.yml service, or a Compose service back into docker run.
- Regex Tester — Test a regular expression against sample text with live match highlighting, capture groups and replace preview. Free, in your browser.