Developers

HTTP status codes, explained properly

A complete, spec-checked reference to every registered HTTP status code, with the common causes behind each one and the codes people most often send by mistake.

Every HTTP response starts with a three-digit number, and that number is a contract. Browsers, caches, load balancers, API clients, uptime monitors and search crawlers all make decisions from it before they read a single byte of the body. The most common HTTP mistake is not an obscure code. It is sending the wrong common code: a 200 for an error, a 403 where 401 belongs, a 503 when the problem is really a rate limit.

This page lists every status code in the IANA HTTP Status Code Registry, with the meaning as written in RFC 9110, Section 15 (the June 2022 specification that consolidated HTTP semantics) or the RFC that added the code. The codes that cause the most confusion have their own pages:

Status code explorer#

Search every registered code by number (404), class (5xx) or keyword (“redirect”, “rate limit”). Open a card for the common cause, what to do about it, the defining spec, and a curl one-liner to check the status yourself. The full tables, with the same data, follow below.

63 status codes

  • 100ContinueThe start of the request was received and not rejected; send the rest

    Where you see it: Large uploads sent with Expect: 100-continue

    What should I do? Nothing to do: it is an interim response. A client that sent Expect: 100-continue should go ahead and send the rest of the request body.

    Defined in: RFC 9110 §15.2.1

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 100
  • 101Switching ProtocolsThe server agrees to change protocol via the Upgrade header

    Where you see it: WebSocket handshakes

    What should I do? Nothing to do: the server agreed to change protocol via the Upgrade header, as in a WebSocket handshake. The rest of the conversation uses the new protocol.

    Defined in: RFC 9110 §15.2.2

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 101
  • 102ProcessingWebDAV interim response for long operations

    Where you see it: Rare outside WebDAV

    What should I do? Nothing to do: it is a WebDAV interim response for a long operation. Keep waiting for the final status code.

    Defined in: RFC 2518 (IANA)

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 102
  • 103Early HintsHeaders (usually Link: rel=preload) the final response is likely to include

    Where you see it: CDNs letting browsers preload CSS and fonts while the page renders

    What should I do? Nothing to do: these are early hints, usually Link: rel=preload headers that let the browser start fetching CSS and fonts. The final response still follows.

    Defined in: RFC 8297

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 103
  • 200OKThe request succeeded; the body depends on the method

    Typical use: A page or API result

    What should I do? Success. If you run the server, never send 200 for an error: retries, caches, alerting and crawlers read the status line, not your JSON. Return the matching 4xx or 5xx with the details in the body.

    Defined in: §15.3.1

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 200
  • 201CreatedOne or more new resources were created, identified by Location or the target URI

    Typical use: Successful POST that creates a record

    What should I do? The resource was created. Look at the Location header (or the target URI) to find the new resource.

    Defined in: §15.3.2

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 201
  • 202AcceptedAccepted for processing, not finished; "intentionally noncommittal"

    Typical use: Queued jobs, async exports

    What should I do? Accepted but not finished: the work is queued. Check the job's status later rather than assuming it succeeded; the code is intentionally noncommittal.

    Defined in: §15.3.3

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 202
  • 203Non-Authoritative InformationSuccess, but a transforming proxy modified the content

    Typical use: Rare

    What should I do? The request succeeded, but a transforming proxy modified the content. If the body looks different from what the origin sent, look at the proxy.

    Defined in: §15.3.4

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 203
  • 204No ContentSuccess with nothing to send back

    Typical use: DELETE, or a PUT that returns no body

    What should I do? Success with no body. Don't call JSON.parse or response.json() on it: an empty body throws 'Unexpected end of JSON input'.

    Defined in: §15.3.5

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 204
  • 205Reset ContentSuccess; the client should reset the document view (for example, clear a form)

    Typical use: Rare

    What should I do? Success: the client should reset the document view, for example by clearing the form that was just submitted.

    Defined in: §15.3.6

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 205
  • 206Partial ContentOnly the requested byte ranges are being sent

    Typical use: Video seeking, resumable downloads

    What should I do? Only the requested byte ranges were sent, as in video seeking or a resumed download. If you expected the whole file, check the Range header your client sent.

    Defined in: §15.3.7

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 206
  • 207Multi-StatusSeveral status values for several resources, in an XML body

    Typical use: WebDAV

    What should I do? WebDAV: the XML body holds a separate status for each resource. Read each one, because some may have failed even though the response as a whole is 207.

    Defined in: RFC 4918

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 207
  • 208Already ReportedWebDAV binding members already listed earlier in the response

    Typical use: WebDAV

    What should I do? WebDAV: these binding members were already listed earlier in the response, so they are not repeated. Nothing to fix.

    Defined in: RFC 5842 (IANA)

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 208
  • 226IM UsedResponse is the result of instance manipulations (delta encoding)

    Typical use: Very rare

    What should I do? The response is the result of instance manipulations such as delta encoding. You will rarely see it; if you do, your client asked for it.

    Defined in: RFC 3229 (IANA)

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 226
  • 300Multiple ChoicesSeveral representations exist; the client may pick one

    Method preserved?: n/a

    What should I do? Several representations exist and the client may pick one. Choose a specific representation and request it directly.

    Defined in: §15.4.1

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 300
  • 301Moved PermanentlyNew permanent URI; future requests should use it

    Method preserved?: Clients may change POST to GET

    What should I do? The resource moved for good: update your links and bookmarks to the new URI in Location. Clients may change a POST into a GET when following it; use 308 if the method must be kept.

    Defined in: §15.4.2

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 301
  • 302FoundTemporarily at a different URI; keep using the original

    Method preserved?: Clients may change POST to GET

    What should I do? A temporary move: keep using the original URL. If you run the site and the page has moved for good, send 301 or 308 instead, which Google treats as strong canonical signals.

    Defined in: §15.4.3

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 302
  • 303See OtherGo and GET a different resource as the answer

    Method preserved?: No: becomes GET by design

    What should I do? Go and GET the resource in Location as the answer; the method becomes GET by design, whatever the original request used.

    Defined in: §15.4.4

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 303
  • 304Not ModifiedA conditional GET found the cached copy still valid

    Method preserved?: n/a

    What should I do? Your conditional GET found the cached copy still valid, so use the copy you already have.

    Defined in: §15.4.5

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 304
  • 305Use ProxyDeprecated

    Method preserved?: n/a

    What should I do? Use Proxy is deprecated. Don't send it, and don't rely on clients honoring it.

    Defined in: §15.4.6

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 305
  • 306(Unused)Reserved; no longer used

    Method preserved?: n/a

    What should I do? Reserved and no longer used. If a server sends it, treat it like any unknown 3xx and report it to the operator.

    Defined in: §15.4.7

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 306
  • 307Temporary RedirectTemporary, and the client MUST NOT change the method

    Method preserved?: Yes

    What should I do? A temporary redirect where the client must not change the method. Repeat the same request, with the same method and body, at the Location URL.

    Defined in: §15.4.8

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 307
  • 308Permanent RedirectPermanent, like 301, but without the method change

    Method preserved?: Yes

    What should I do? A permanent redirect that keeps the method and body. Update your links, and use 308 instead of 301 when a POST must stay a POST.

    Defined in: §15.4.9

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 308
  • 400Bad RequestThe server cannot or will not process a request it perceives as a client error

    Common cause: Malformed JSON, bad query parameters, oversized cookies

    What should I do? The server perceived a client error. Check for malformed JSON, bad query parameters or oversized cookies, fix the request, then try again; repeating the identical request is pointless.

    Defined in: §15.5.1

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 400
  • 401UnauthorizedNo valid authentication credentials; MUST include WWW-Authenticate

    Common cause: Missing or expired token

    What should I do? No valid credentials: log in again or refresh your token, then retry. If you run the server, always include a WWW-Authenticate challenge, which RFC 9110 requires. Full guide →

    Defined in: §15.5.2

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 401
  • 402Payment RequiredReserved for future use

    Common cause: Some APIs use it informally for billing problems

    What should I do? Reserved for future use. Some APIs use it informally for billing problems, so check your account's billing status in that API's dashboard.

    Defined in: §15.5.3

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 402
  • 403ForbiddenUnderstood, but refused; credentials will not help

    Common cause: Logged in without permission, IP or WAF block, file permissions

    What should I do? The server understood but refuses, and logging in again will not help. Check you are signed in with the right account; operators should look at roles, scopes, WAF or IP rules and file permissions. Full guide →

    Defined in: §15.5.4

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 403
  • 404Not FoundNo current representation, or the server will not say whether one exists

    Common cause: Typos, deleted pages, broken links, wrong routes

    What should I do? Nothing at that address. Check the URL for typos, trim the path from the right, or search the site. If you run it, add 301s for moved pages and make sure your error page really returns 404, not 200. Full guide →

    Defined in: §15.5.5

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 404
  • 405Method Not AllowedMethod known but not supported here; MUST include Allow

    Common cause: POST to a GET-only route

    What should I do? The method isn't supported on this URL. Check the Allow header in the response for the methods that are, for example a POST sent to a GET-only route.

    Defined in: §15.5.6

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 405
  • 406Not AcceptableNothing matches the client's Accept* headers

    Common cause: Strict content negotiation

    What should I do? Nothing matches the Accept headers your client sent. Loosen or correct the Accept header, or ask for a format the server offers.

    Defined in: §15.5.7

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 406
  • 407Proxy Authentication RequiredLike 401, but for a proxy

    Common cause: Corporate proxies

    What should I do? Like 401, but for a proxy: authenticate with the proxy, often a corporate one, before retrying.

    Defined in: §15.5.8

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 407
  • 408Request TimeoutThe full request did not arrive in time

    Common cause: Slow uploads, idle keep-alive connections

    What should I do? The full request did not arrive in time. Retry, and for slow uploads check your connection; idle keep-alive connections can also trigger it.

    Defined in: §15.5.9

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 408
  • 409ConflictConflicts with the current state of the resource

    Common cause: Edit conflicts, duplicate unique keys

    What should I do? The request conflicts with the current state of the resource, such as an edit conflict or a duplicate unique key. Fetch the latest version, resolve the conflict, then resend.

    Defined in: §15.5.10

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 409
  • 410GoneNo longer available, and likely permanent

    Common cause: Deliberately retired pages or promotions

    What should I do? The resource was removed on purpose and is likely gone for good. Remove links to it. If you run the site, use 410 only for deliberate removals with no replacement. Full guide →

    Defined in: §15.5.11

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 410
  • 411Length RequiredA Content-Length is required

    Common cause: Clients streaming without length

    What should I do? The server requires a Content-Length header. Send the request with its length instead of streaming it without one.

    Defined in: §15.5.12

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 411
  • 412Precondition FailedA conditional header such as If-Match evaluated false

    Common cause: Optimistic concurrency with ETags

    What should I do? A conditional header such as If-Match evaluated false: someone changed the resource since you fetched it. Fetch it again, reapply your change and retry with the new ETag.

    Defined in: §15.5.13

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 412
  • 413Content Too LargeThe request body is larger than the server will process

    Common cause: Upload limits such as nginx client_max_body_size

    What should I do? The request body is larger than the server will process. Send a smaller body; operators can raise upload limits such as nginx client_max_body_size if appropriate.

    Defined in: §15.5.14

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 413
  • 414URI Too LongThe target URI is longer than the server will interpret

    Common cause: A POST converted into a GET with a huge query string; redirect loops

    What should I do? The URI is too long for the server. Move large data out of the query string into a POST body, and check for redirect loops that keep growing the URL.

    Defined in: §15.5.15

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 414
  • 415Unsupported Media TypeThe body's format is not supported

    Common cause: Sending form data to a JSON-only endpoint

    What should I do? The server doesn't support the body's format. Send the format it expects and set Content-Type to match, for example JSON instead of form data.

    Defined in: §15.5.16

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 415
  • 416Range Not SatisfiableThe requested byte ranges cannot be served

    Common cause: Resuming a download past the end of a file

    What should I do? The requested byte range can't be served, for example when resuming a download past the end of the file. Check the range you asked for against the file's size.

    Defined in: §15.5.17

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 416
  • 417Expectation FailedThe Expect header could not be met

    Common cause: Proxies that do not support 100-continue

    What should I do? The Expect header could not be met, often by a proxy that does not support 100-continue. Send the request without Expect: 100-continue.

    Defined in: §15.5.18

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 417
  • 418(Unused)Reserved; originally the "I'm a teapot" joke

    Common cause: Easter eggs Meet the teapot →

    What should I do? Reserved: it began as the 'I'm a teapot' joke in RFC 2324. Treat it as an Easter egg, and don't use it to mean anything in a real API.

    Defined in: §15.5.19

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 418
  • 421Misdirected RequestThis server cannot answer authoritatively for that URI

    Common cause: HTTP/2 connection reuse across hostnames with different certificates

    What should I do? This server can't answer authoritatively for that URI, often after HTTP/2 connection reuse across hostnames with different certificates. Make sure the request goes over a connection to the right host.

    Defined in: §15.5.20

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 421
  • 422Unprocessable ContentSyntax is fine, but the instructions cannot be processed

    Common cause: Validation failures on well-formed JSON

    What should I do? The syntax is fine but the content failed validation. Read the error body for the field that failed, fix the value, then resend.

    Defined in: §15.5.21

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 422
  • 423LockedThe resource is locked

    Common cause: WebDAV

    What should I do? WebDAV: the resource is locked. Wait for the lock to be released, or release it if you hold it, then retry.

    Defined in: RFC 4918

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 423
  • 424Failed DependencyFailed because an earlier action failed

    Common cause: WebDAV

    What should I do? WebDAV: this action failed because an earlier action it depended on failed. Fix the earlier failure first.

    Defined in: RFC 4918

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 424
  • 425Too EarlyThe server will not risk processing a possibly replayed request

    Common cause: TLS 1.3 early data (0-RTT)

    What should I do? The server won't risk processing a request that might be replayed, as with TLS 1.3 early data (0-RTT). Retry after the handshake completes.

    Defined in: RFC 8470

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 425
  • 426Upgrade RequiredRefused on this protocol; MUST send Upgrade

    Common cause: Services requiring a newer protocol

    What should I do? Refused on this protocol. Check the Upgrade header in the response and switch to the protocol it names.

    Defined in: §15.5.22

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 426
  • 428Precondition RequiredThe server requires the request to be conditional

    Common cause: Preventing lost updates; require If-Match

    What should I do? The server requires a conditional request to prevent lost updates. Fetch the resource, then resend your change with If-Match and its ETag.

    Defined in: RFC 6585 §3

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 428
  • 429Too Many RequestsToo many requests in a given time (rate limiting)

    Common cause: API quotas, login throttling, scrapers

    What should I do? You hit a rate limit. Stop retrying immediately: honor Retry-After, otherwise back off exponentially with jitter. If you run the server, return 429 (not 503) for per-client limits and send Retry-After. Full guide →

    Defined in: RFC 6585 §4

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 429
  • 431Request Header Fields Too LargeHeaders, in total or one of them, are too large

    Common cause: Bloated cookies

    What should I do? The request headers, in total or one of them, are too large. Bloated cookies are the common cause, so clearing the site's cookies is the first thing to try.

    Defined in: RFC 6585 §5

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 431
  • 451Unavailable For Legal ReasonsAccess denied as a consequence of a legal demand

    Common cause: Court orders, regional legal blocks

    What should I do? Access was denied as a consequence of a legal demand, such as a court order or a regional legal block. There is nothing to fix in the request itself.

    Defined in: RFC 7725 §3

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 451
  • 500Internal Server ErrorAn unexpected condition prevented fulfilling the request

    Common cause: Unhandled exceptions, bad config, failed deploys

    What should I do? The server hit an unexpected condition. Visitors can wait a moment and reload once. Operators should check the application log for the stack trace and ask what changed: a deploy, config, dependency or credential. Full guide →

    Defined in: §15.6.1

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 500
  • 501Not ImplementedThe server does not support the required functionality

    Common cause: Unrecognised method

    What should I do? The server doesn't support the functionality required, typically an unrecognised method. Use a method the server supports.

    Defined in: §15.6.2

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 501
  • 502Bad GatewayA gateway or proxy got an invalid response from upstream

    Common cause: App crashed, connection refused, upstream reset

    What should I do? A gateway or proxy got an invalid response from upstream. Visitors can wait a minute and reload. Operators should check whether the app is running and listening where the proxy points, and read the proxy's error log. Full guide →

    Defined in: §15.6.3

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 502
  • 503Service UnavailableTemporary overload or maintenance; may send Retry-After

    Common cause: Deploys, maintenance mode, load shedding

    What should I do? The service is temporarily overloaded or in maintenance. Wait and retry, honoring Retry-After if present. Operators should send 503 deliberately for maintenance and use 429, not 503, for per-client rate limits. Full guide →

    Defined in: §15.6.4

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 503
  • 504Gateway TimeoutA gateway or proxy did not get a timely response from upstream

    Common cause: Slow queries, long-running requests

    What should I do? A gateway or proxy didn't get a timely response from upstream. Before resubmitting a form, check whether the action completed. Operators should fix the slow path rather than raising every timeout. Full guide →

    Defined in: §15.6.5

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 504
  • 505HTTP Version Not SupportedThe major HTTP version is not supported

    Common cause: Very old or very unusual clients

    What should I do? The server doesn't support the major HTTP version used. Retry with a common HTTP version; this mostly affects very old or unusual clients.

    Defined in: §15.6.6

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 505
  • 506Variant Also NegotiatesContent negotiation configuration error

    Common cause: Rare

    What should I do? A content negotiation configuration error on the server. Nothing to fix in your request; report it to the site's operator.

    Defined in: RFC 2295 (IANA)

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 506
  • 507Insufficient StorageThe server cannot store what is needed to complete the request

    Common cause: WebDAV, full disks

    What should I do? The server can't store what it needs to complete the request, as with a full disk. Operators should free or add storage; clients can retry later.

    Defined in: RFC 4918

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 507
  • 508Loop DetectedAn infinite loop was found while processing

    Common cause: WebDAV bindings

    What should I do? WebDAV: the server found an infinite loop while processing, typically from bindings. Operators should check the binding configuration.

    Defined in: RFC 5842 (IANA)

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 508
  • 510Not ExtendedMarked obsoleted in the registry

    Common cause: Do not use

    What should I do? Marked obsoleted in the IANA registry. Do not use it.

    Defined in: RFC 2774 (IANA)

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 510
  • 511Network Authentication RequiredThe client must authenticate to gain network access

    Common cause: Captive portals on hotel and airport Wi-Fi

    What should I do? You need to authenticate to get network access, as on hotel and airport Wi-Fi captive portals. Open any web page in a browser to reach the sign-in screen.

    Defined in: RFC 6585 §6

    curl -sI https://example.com/your/path | head -n 1
    # look for: HTTP/… 511

How the five classes work#

RFC 9110 says the first digit defines the class of response, and that a client which does not recognise a specific code must treat it as the x00 code of its class. An unknown 471 is handled like 400; an unknown 599 like 500. That rule is why picking the right class matters more than picking a clever specific code.

ClassMeaning in RFC 9110Who probably needs to act
1xxInformational: an interim response before the final oneNobody; the client keeps waiting
2xxSuccessful: the request was received, understood and acceptedNobody
3xxRedirection: further action is needed to complete the requestThe client follows the Location
4xxClient error: the client "seems to have erred"The caller must change the request
5xxServer error: the server "is aware that it has erred or is incapable of performing the requested method"The operator of the server

1xx Informational#

CodeNameWhat it meansWhere you see itSpec
100ContinueThe start of the request was received and not rejected; send the restLarge uploads sent with Expect: 100-continueRFC 9110 §15.2.1
101Switching ProtocolsThe server agrees to change protocol via the Upgrade headerWebSocket handshakesRFC 9110 §15.2.2
102ProcessingWebDAV interim response for long operationsRare outside WebDAVRFC 2518 (IANA)
103Early HintsHeaders (usually Link: rel=preload) the final response is likely to includeCDNs letting browsers preload CSS and fonts while the page rendersRFC 8297

2xx Successful#

CodeNameWhat it meansTypical useSpec
200OKThe request succeeded; the body depends on the methodA page or API result§15.3.1
201CreatedOne or more new resources were created, identified by Location or the target URISuccessful POST that creates a record§15.3.2
202AcceptedAccepted for processing, not finished; "intentionally noncommittal"Queued jobs, async exports§15.3.3
203Non-Authoritative InformationSuccess, but a transforming proxy modified the contentRare§15.3.4
204No ContentSuccess with nothing to send backDELETE, or a PUT that returns no body§15.3.5
205Reset ContentSuccess; the client should reset the document view (for example, clear a form)Rare§15.3.6
206Partial ContentOnly the requested byte ranges are being sentVideo seeking, resumable downloads§15.3.7
207Multi-StatusSeveral status values for several resources, in an XML bodyWebDAVRFC 4918
208Already ReportedWebDAV binding members already listed earlier in the responseWebDAVRFC 5842 (IANA)
226IM UsedResponse is the result of instance manipulations (delta encoding)Very rareRFC 3229 (IANA)

HTTP/1.1 200 OK with {"success": false, "error": "User not found"}

HTTP/1.1 404 Not Found with Content-Type: application/problem+json and the details in the body

Retries, caches, alerting and crawlers read the status line, not your JSON. A 200 tells all of them that the request worked. RFC 9457 defines a standard error body so you do not have to invent one.

3xx Redirection#

CodeNameWhat it meansMethod preserved?Spec
300Multiple ChoicesSeveral representations exist; the client may pick onen/a§15.4.1
301Moved PermanentlyNew permanent URI; future requests should use itClients may change POST to GET§15.4.2
302FoundTemporarily at a different URI; keep using the originalClients may change POST to GET§15.4.3
303See OtherGo and GET a different resource as the answerNo: becomes GET by design§15.4.4
304Not ModifiedA conditional GET found the cached copy still validn/a§15.4.5
305Use ProxyDeprecatedn/a§15.4.6
306(Unused)Reserved; no longer usedn/a§15.4.7
307Temporary RedirectTemporary, and the client MUST NOT change the methodYes§15.4.8
308Permanent RedirectPermanent, like 301, but without the method changeYes§15.4.9

The usual mistake is reaching for 302 by habit. If a page has moved for good, send 301 or 308. Google's documentation says it treats 301 and 308 as strong signals that the target should be canonical, and 302, 303 and 307 as weak signals. Google's crawlers follow up to 10 redirect hops by default, so long chains waste crawling and can break.

4xx Client errors#

Per RFC 9110 §15.5, a 4xx response should carry an explanation of the error and say whether it is temporary or permanent. The caller has to change something before trying again; repeating the identical request is usually pointless (429 is the exception: wait, then retry).

CodeNameWhat it meansCommon causeSpec
400Bad RequestThe server cannot or will not process a request it perceives as a client errorMalformed JSON, bad query parameters, oversized cookies§15.5.1
401UnauthorizedNo valid authentication credentials; MUST include WWW-AuthenticateMissing or expired token§15.5.2
402Payment RequiredReserved for future useSome APIs use it informally for billing problems§15.5.3
403ForbiddenUnderstood, but refused; credentials will not helpLogged in without permission, IP or WAF block, file permissions§15.5.4
404Not FoundNo current representation, or the server will not say whether one existsTypos, deleted pages, broken links, wrong routes§15.5.5
405Method Not AllowedMethod known but not supported here; MUST include AllowPOST to a GET-only route§15.5.6
406Not AcceptableNothing matches the client's Accept* headersStrict content negotiation§15.5.7
407Proxy Authentication RequiredLike 401, but for a proxyCorporate proxies§15.5.8
408Request TimeoutThe full request did not arrive in timeSlow uploads, idle keep-alive connections§15.5.9
409ConflictConflicts with the current state of the resourceEdit conflicts, duplicate unique keys§15.5.10
410GoneNo longer available, and likely permanentDeliberately retired pages or promotions§15.5.11
411Length RequiredA Content-Length is requiredClients streaming without length§15.5.12
412Precondition FailedA conditional header such as If-Match evaluated falseOptimistic concurrency with ETags§15.5.13
413Content Too LargeThe request body is larger than the server will processUpload limits such as nginx client_max_body_size§15.5.14
414URI Too LongThe target URI is longer than the server will interpretA POST converted into a GET with a huge query string; redirect loops§15.5.15
415Unsupported Media TypeThe body's format is not supportedSending form data to a JSON-only endpoint§15.5.16
416Range Not SatisfiableThe requested byte ranges cannot be servedResuming a download past the end of a file§15.5.17
417Expectation FailedThe Expect header could not be metProxies that do not support 100-continue§15.5.18
418(Unused)Reserved; originally the "I'm a teapot" jokeEaster eggs§15.5.19
421Misdirected RequestThis server cannot answer authoritatively for that URIHTTP/2 connection reuse across hostnames with different certificates§15.5.20
422Unprocessable ContentSyntax is fine, but the instructions cannot be processedValidation failures on well-formed JSON§15.5.21
423LockedThe resource is lockedWebDAVRFC 4918
424Failed DependencyFailed because an earlier action failedWebDAVRFC 4918
425Too EarlyThe server will not risk processing a possibly replayed requestTLS 1.3 early data (0-RTT)RFC 8470
426Upgrade RequiredRefused on this protocol; MUST send UpgradeServices requiring a newer protocol§15.5.22
428Precondition RequiredThe server requires the request to be conditionalPreventing lost updates; require If-MatchRFC 6585 §3
429Too Many RequestsToo many requests in a given time (rate limiting)API quotas, login throttling, scrapersRFC 6585 §4
431Request Header Fields Too LargeHeaders, in total or one of them, are too largeBloated cookiesRFC 6585 §5
451Unavailable For Legal ReasonsAccess denied as a consequence of a legal demandCourt orders, regional legal blocksRFC 7725 §3

5xx Server errors#

CodeNameWhat it meansCommon causeSpec
500Internal Server ErrorAn unexpected condition prevented fulfilling the requestUnhandled exceptions, bad config, failed deploys§15.6.1
501Not ImplementedThe server does not support the required functionalityUnrecognised method§15.6.2
502Bad GatewayA gateway or proxy got an invalid response from upstreamApp crashed, connection refused, upstream reset§15.6.3
503Service UnavailableTemporary overload or maintenance; may send Retry-AfterDeploys, maintenance mode, load shedding§15.6.4
504Gateway TimeoutA gateway or proxy did not get a timely response from upstreamSlow queries, long-running requests§15.6.5
505HTTP Version Not SupportedThe major HTTP version is not supportedVery old or very unusual clients§15.6.6
506Variant Also NegotiatesContent negotiation configuration errorRareRFC 2295 (IANA)
507Insufficient StorageThe server cannot store what is needed to complete the requestWebDAV, full disksRFC 4918
508Loop DetectedAn infinite loop was found while processingWebDAV bindingsRFC 5842 (IANA)
510Not ExtendedMarked obsoleted in the registryDo not useRFC 2774 (IANA)
511Network Authentication RequiredThe client must authenticate to gain network accessCaptive portals on hotel and airport Wi-FiRFC 6585 §6

Codes you will see that are not in the registry#

Cloudflare returns its own 520 to 526 and 530 to describe problems between its edge and your origin, such as 521 (web server is down), 522 (connection timed out) and 524 (a timeout occurred). nginx logs a non-standard 499 when, as its source code puts it, "a client has closed the connection before we even try to send the HTTP header to it." These are useful diagnostics, but generic clients only know they are 5xx or 4xx.

The mistakes that matter most#

403 Forbidden for a request with no token at all

401 Unauthorized with a WWW-Authenticate challenge

401 means "authenticate and try again"; 403 means "authenticating will not help." Details on the 401 vs 403 page.

A friendly "Page not found" page served with status 200

The same friendly page served with status 404

Google calls this a soft 404 and flags it in Search Console. See 404 Not Found.

Rate-limited requests rejected with 503 (nginx limit_req's default)

limit_req_status 429; plus a Retry-After header

A 503 tells clients and monitors that your server is unhealthy. A 429 tells the caller that they should slow down. See 429 Too Many Requests.

Checking a status code yourself#

The fastest way to see the real status line, without a browser's friendly error page in the way, is curl:

# Status line and headers only (HEAD request)
curl -I https://example.com/some/page

# A real GET, but print only the status code
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/some/page

# Follow redirects and show every hop
curl -sIL https://example.com/old-url | grep -iE "^(HTTP|location)"

Frequently asked questions

How many HTTP status codes are there?

The IANA HTTP Status Code Registry is the authoritative list. RFC 9110 defines the core set (100 through 505), and other RFCs add codes such as 429 and 511 (RFC 6585), 451 (RFC 7725), 103 (RFC 8297) and the WebDAV codes from RFC 4918. Codes outside that registry, such as Cloudflare's 52x family, are vendor-specific.

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

It began as an April Fools' joke in RFC 2324. RFC 9110 now lists 418 as (Unused) and keeps it reserved in the registry because it was deployed as a joke so often that it cannot safely be reassigned. Do not use it to mean anything in a real API.

What is the difference between 301 and 308?

Both mean the resource has moved permanently. RFC 9110 notes that, for historical reasons, clients may change a POST into a GET when following a 301. A 308 forbids that method change, so use 308 when the method and body must be preserved.

Should an API return 200 with an error message in the body?

No. The status code is how clients, caches, monitoring and crawlers learn that something failed. Return the matching 4xx or 5xx code and put the details in the body, ideally in the RFC 9457 problem details format (application/problem+json).

Which status code should I use for validation errors?

Use 400 Bad Request when the request is malformed, and 422 Unprocessable Content when it is well-formed but semantically invalid (for example, a well-formed JSON body whose values fail business rules). 422 was originally a WebDAV code and is now defined in RFC 9110.

Sources

Every factual claim on this page links to one of these. Checked October 2026. See how we source.

  1. RFC 9110: HTTP Semantics, Section 15 (Status Codes) rfc-editor.org
  2. IANA HTTP Status Code Registry iana.org
  3. RFC 6585: Additional HTTP Status Codes (428, 429, 431, 511) rfc-editor.org
  4. RFC 7725: An HTTP Status Code to Report Legal Obstacles (451) rfc-editor.org
  5. RFC 8297: An HTTP Status Code for Indicating Hints (103) rfc-editor.org
  6. RFC 8470: Using Early Data in HTTP (425) rfc-editor.org
  7. RFC 4918: HTTP Extensions for WebDAV (207, 423, 424, 507) rfc-editor.org
  8. RFC 2324: Hyper Text Coffee Pot Control Protocol (418) rfc-editor.org
  9. RFC 9457: Problem Details for HTTP APIs rfc-editor.org
  10. MDN: HTTP response status codes developer.mozilla.org
  11. Google Search Central: How HTTP status codes affect Google Search developers.google.com
  12. Cloudflare: Cloudflare 5xx errors developers.cloudflare.com
  13. nginx source: ngx_http_request.h (499 definition) github.com