Every HTTP response starts with a three-digit status code. The first digit is the class; the other two identify the specific condition. This page lists every code in the IANA registry, with the RFC that defines it, what it means, and what to check when you see it. Unassigned numbers are omitted; codes invented by individual vendors (Cloudflare’s 52x, nginx’s 499) are noted at the end.
1xx Informational
The request was received and processing continues. Rare outside protocol upgrades and early hints.
- 100
ContinueRFC 9110 §15.2.1
The server has received the request headers and the client should send the body. Sent in response to an
Expect: 100-continueheader; most clients never see it. - 101
Switching ProtocolsRFC 9110 §15.2.2
The server agrees to change protocol as requested by the
Upgradeheader. This is how a WebSocket handshake completes over HTTP/1.1. - 102
ProcessingRFC 2518 (WebDAV)
Deprecated interim response for long-running WebDAV requests.
- 103
Early HintsRFC 8297
Sent before the final response so the browser can start preloading resources named in
Linkheaders. Used by CDNs to shave load time.
2xx Success
The request was received, understood and accepted.
- 200
OKRFC 9110 §15.3.1
The request succeeded. The body depends on the method: the resource for GET, the result for POST. Cacheable by default.
- 201
CreatedRFC 9110 §15.3.2
A new resource was created. Return a
Locationheader pointing at it. The normal success code for POST that creates and for PUT to a new URL. - 202
AcceptedRFC 9110 §15.3.3
The request was accepted for processing but is not finished. Use it for queued jobs, and give the client a way to poll for the result.
- 203
Non-Authoritative InformationRFC 9110 §15.3.4
A transforming proxy modified the 200 response. Rare.
- 204
No ContentRFC 9110 §15.3.5
Success with no body. Typical for DELETE, for PUT that updates in place, and for form submissions that should leave the page as-is. Must not include a body.
- 205
Reset ContentRFC 9110 §15.3.6
Like 204, but the client should reset the form or view. Rarely used.
- 206
Partial ContentRFC 9110 §15.3.7
The response contains the byte range asked for in the
Rangeheader. This is how video seeking and resumable downloads work. - 207
Multi-StatusRFC 4918 (WebDAV)
An XML body carries a status for each of several resources.
- 208
Already ReportedRFC 5842 (WebDAV)
Avoids repeating members of a binding in a 207 response.
- 226
IM UsedRFC 3229
The response is a delta against a previous representation. Essentially unused.
3xx Redirection
The client needs to take further action, usually following a Location header.
- 300
Multiple ChoicesRFC 9110 §15.4.1
Several representations exist and the client should pick one. Almost never used in practice; servers negotiate instead.
- 301
Moved PermanentlyRFC 9110 §15.4.2
The resource has a new permanent URL in
Location. Browsers cache it, search engines transfer ranking to the new URL. Clients may change POST to GET; use 308 if the method must be kept. - 302
FoundRFC 9110 §15.4.3
Temporary redirect. Historically browsers turned POST into GET when following it, which RFC 9110 now permits. Use 307 when the method must be preserved. Not cached unless headers say so.
- 303
See OtherRFC 9110 §15.4.4
Redirect the client to fetch a different resource with GET. The standard answer to a successful form POST (POST → redirect → GET) so that refresh does not resubmit.
- 304
Not ModifiedRFC 9110 §15.4.5
A conditional request (
If-None-Match,If-Modified-Since) matched; the cached copy is still valid. No body. This is what makes caching cheap. - 305
Use ProxyRFC 9110 §15.4.6
Deprecated for security reasons. Do not use.
- 306
(Unused)RFC 9110 §15.4.7
Reserved; was “Switch Proxy” in a draft.
- 307
Temporary RedirectRFC 9110 §15.4.8
Like 302, but the client must repeat the request with the same method and body at the new URL.
- 308
Permanent RedirectRFC 9110 §15.4.9
Like 301, but the method and body must be preserved. Use it for permanent moves of API endpoints that accept POST or PUT.
4xx Client error
The request is wrong or cannot be fulfilled as sent. Fix the request.
- 400
Bad RequestRFC 9110 §15.5.1
The server cannot process the request because of a client error: malformed syntax, invalid JSON, a missing required field. Explain what was wrong in the body. If the problem is semantic rather than syntactic, 422 is more specific.
- 401
UnauthorizedRFC 9110 §15.5.2
Authentication is required and was missing or invalid. Despite the name, this means unauthenticated. The response must include a
WWW-Authenticateheader. For a valid identity that lacks permission, use 403. - 402
Payment RequiredRFC 9110 §15.5.3
Reserved for future use. Some APIs use it for quota or billing failures.
- 403
ForbiddenRFC 9110 §15.5.4
The server understood the request and knows who you are, but refuses to authorise it. Re-authenticating will not help. Some servers return 404 instead, to avoid revealing that a resource exists.
- 404
Not FoundRFC 9110 §15.5.5
No resource at this URL. The most common error on the web. Check the path, trailing slashes, case (most servers are case-sensitive), and whether the route is registered. For a resource that existed and was deliberately removed, 410 is more precise.
- 405
Method Not AllowedRFC 9110 §15.5.6
The URL exists but does not support this method, for example POST to a read-only endpoint. The response must list what is allowed in an
Allowheader. - 406
Not AcceptableRFC 9110 §15.5.7
The server cannot produce a representation matching the request’s
Acceptheaders. Most servers ignore Accept and return the default instead. - 407
Proxy Authentication RequiredRFC 9110 §15.5.8
Like 401, but from a proxy, with
Proxy-Authenticate. - 408
Request TimeoutRFC 9110 §15.5.9
The server gave up waiting for the client to finish sending the request. Typically an idle keep-alive connection; clients may retry.
- 409
ConflictRFC 9110 §15.5.10
The request conflicts with the current state: creating something that already exists, an edit based on a stale version, a unique constraint violation. Tell the client how to resolve it.
- 410
GoneRFC 9110 §15.5.11
The resource existed and has been permanently removed. Search engines drop 410 URLs faster than 404s.
- 411
Length RequiredRFC 9110 §15.5.12
The server needs a
Content-Lengthheader and the request had none (chunked encoding not accepted). - 412
Precondition FailedRFC 9110 §15.5.13
A conditional header such as
If-Matchdid not match. The standard way to implement optimistic concurrency with ETags. - 413
Content Too LargeRFC 9110 §15.5.14
The request body exceeds the server’s limit. Formerly “Payload Too Large”. Common with uploads behind nginx (
client_max_body_size) or API gateways. - 414
URI Too LongRFC 9110 §15.5.15
The URL exceeds the server’s limit (often 8 KB). Usually a GET carrying data that belongs in a POST body.
- 415
Unsupported Media TypeRFC 9110 §15.5.16
The
Content-Typeof the request body is not supported. A JSON API returns this when it receives form data, or when the header is missing entirely. - 416
Range Not SatisfiableRFC 9110 §15.5.17
The requested byte range is outside the resource. Respond with
Content-Range: bytes */size. - 417
Expectation FailedRFC 9110 §15.5.18
The
Expectheader could not be met. Almost always about100-continue. - 418
(Unused)RFC 9110 §15.5.19
RFC 2324 defined “I’m a teapot” as an April Fools’ joke. RFC 9110 marks the code unused; some frameworks still ship it.
- 421
Misdirected RequestRFC 9110 §15.5.20
The request reached a server that cannot answer for this authority. Seen with HTTP/2 connection coalescing across hostnames.
- 422
Unprocessable ContentRFC 9110 §15.5.21
The syntax is fine but the content is semantically invalid: a well-formed JSON body that fails validation rules. Previously “Unprocessable Entity” (WebDAV). Popular in REST APIs for validation errors.
- 423
LockedRFC 4918 (WebDAV)
The resource is locked.
- 424
Failed DependencyRFC 4918 (WebDAV)
The request failed because a request it depended on failed.
- 425
Too EarlyRFC 8470
The server refuses to process a request that might be replayed (TLS 1.3 early data). Clients should retry after the handshake completes.
- 426
Upgrade RequiredRFC 9110 §15.5.22
The client must switch to a different protocol named in
Upgrade, for example TLS. - 428
Precondition RequiredRFC 6585
The server requires the request to be conditional (an
If-Matchheader) to prevent lost updates. - 429
Too Many RequestsRFC 6585
Rate limit exceeded. Include
Retry-After. Clients should back off exponentially; the response is a signal, not a failure of the request itself. - 431
Request Header Fields Too LargeRFC 6585
Headers exceed the server’s limit. Usually caused by oversized cookies; clearing them fixes it for the user, shrinking them fixes it for everyone.
- 451
Unavailable For Legal ReasonsRFC 7725
Access blocked by a legal demand such as a court order or a geographic restriction. The number references Fahrenheit 451.
5xx Server error
The request was valid but the server failed to fulfil it. Fix the server, or wait and retry.
- 500
Internal Server ErrorRFC 9110 §15.6.1
The server hit an unexpected condition: an unhandled exception, a crashed worker, a misconfiguration. Look at the server logs; the response body is deliberately vague. Never expose stack traces to clients in production.
- 501
Not ImplementedRFC 9110 §15.6.2
The server does not recognise the request method at all. Different from 405, where the method is known but not allowed for this resource.
- 502
Bad GatewayRFC 9110 §15.6.3
A proxy or load balancer received an invalid response from the upstream server: the app crashed, is restarting, returned garbage, or the proxy cannot reach it (wrong port, unix socket permissions). Check the upstream first, then the proxy’s error log.
- 503
Service UnavailableRFC 9110 §15.6.4
The server is temporarily unable to handle the request: overloaded, in maintenance, or all workers busy. Include
Retry-After. This is the correct code for a planned maintenance page; search engines treat it as temporary. - 504
Gateway TimeoutRFC 9110 §15.6.5
A proxy waited for the upstream and it did not answer in time. Either the upstream is slow (a long query, a hung dependency) or the proxy timeout (e.g. nginx
proxy_read_timeout, default 60 s) is shorter than the work takes. - 505
HTTP Version Not SupportedRFC 9110 §15.6.6
The server refuses to support the HTTP version used in the request.
- 506
Variant Also NegotiatesRFC 2295
A configuration error in transparent content negotiation. Essentially unused.
- 507
Insufficient StorageRFC 4918 (WebDAV)
The server cannot store the representation.
- 508
Loop DetectedRFC 5842 (WebDAV)
Infinite loop while processing a request with
Depth: infinity. - 510
Not Extended (obsoleted)RFC 2774
Historic; the underlying extension framework was never adopted.
- 511
Network Authentication RequiredRFC 6585
The client must authenticate to the network, as in a captive portal at a hotel or airport. Sent by the intercepting proxy, not the origin.
Codes you will meet that are not in the registry
| Code | Where | Meaning |
|---|---|---|
| 499 | nginx | Client closed the connection before the server responded. Appears only in access logs. |
| 520–527 | Cloudflare | Problems between Cloudflare and the origin: 520 unknown error, 521 origin down, 522 connection timed out, 523 origin unreachable, 524 timeout waiting for origin, 525 SSL handshake failed, 526 invalid SSL certificate, 527 Railgun error. |
| 530 | Cloudflare | Origin DNS error or a 1xxx-series Cloudflare error shown with an explanatory page. |
| 509 | cPanel / Apache hosts | Bandwidth limit exceeded. Non-standard. |
Choosing a code in your own API
- Created something? 201 with a
Location. Deleted or updated with nothing to return? 204. - Body cannot be parsed? 400. Parsed but fails validation? 422 (or 400 if you prefer one code for all client input errors; be consistent).
- No credentials or bad credentials? 401 with
WWW-Authenticate. Good credentials, no permission? 403. See 401 vs 403. - Rate limited? 429 with
Retry-After. Down for maintenance? 503 withRetry-After. - Redirecting a POST? 303 to send the client to a GET, 307 to replay the POST, 308 if the move is permanent.
- Never return 200 with an error in the body. Clients, proxies and monitoring rely on the status code.
Checking a status code from the command line
curl -I https://example.com/path # headers only, shows "HTTP/2 301"
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/path
curl -L -v https://example.com/path 2>&1 | grep '^< HTTP' # follow redirects, show each hop