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
Continue
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 Protocols
The server agrees to change protocol as requested by the
Upgradeheader. This is how a WebSocket handshake completes over HTTP/1.1. - 102
Processing
Deprecated interim response for long-running WebDAV requests.
- 103
Early Hints
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
OK
The request succeeded. The body depends on the method: the resource for GET, the result for POST. Cacheable by default.
- 201
Created
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
Accepted
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 Information
A transforming proxy modified the 200 response. Rare.
- 204
No Content
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 Content
Like 204, but the client should reset the form or view. Rarely used.
- 206
Partial Content
The response contains the byte range asked for in the
Rangeheader. This is how video seeking and resumable downloads work. - 207
Multi-Status
An XML body carries a status for each of several resources.
- 208
Already Reported
Avoids repeating members of a binding in a 207 response.
- 226
IM Used
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 Choices
Several representations exist and the client should pick one. Almost never used in practice; servers negotiate instead.
- 301
Moved Permanently
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
Found
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 Other
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 Modified
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 Proxy
Deprecated for security reasons. Do not use.
- 306
(Unused)
Reserved; was “Switch Proxy” in a draft.
- 307
Temporary Redirect
Like 302, but the client must repeat the request with the same method and body at the new URL.
- 308
Permanent Redirect
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 Request
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
Unauthorized
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 Required
Reserved for future use. Some APIs use it for quota or billing failures.
- 403
Forbidden
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 Found
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 Allowed
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 Acceptable
The server cannot produce a representation matching the request’s
Acceptheaders. Most servers ignore Accept and return the default instead. - 407
Proxy Authentication Required
Like 401, but from a proxy, with
Proxy-Authenticate. - 408
Request Timeout
The server gave up waiting for the client to finish sending the request. Typically an idle keep-alive connection; clients may retry.
- 409
Conflict
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
Gone
The resource existed and has been permanently removed. Search engines drop 410 URLs faster than 404s.
- 411
Length Required
The server needs a
Content-Lengthheader and the request had none (chunked encoding not accepted). - 412
Precondition Failed
A conditional header such as
If-Matchdid not match. The standard way to implement optimistic concurrency with ETags. - 413
Content Too Large
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 Long
The URL exceeds the server’s limit (often 8 KB). Usually a GET carrying data that belongs in a POST body.
- 415
Unsupported Media Type
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 Satisfiable
The requested byte range is outside the resource. Respond with
Content-Range: bytes */size. - 417
Expectation Failed
The
Expectheader could not be met. Almost always about100-continue. - 418
(Unused)
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 Request
The request reached a server that cannot answer for this authority. Seen with HTTP/2 connection coalescing across hostnames.
- 422
Unprocessable Content
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
Locked
The resource is locked.
- 424
Failed Dependency
The request failed because a request it depended on failed.
- 425
Too Early
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 Required
The client must switch to a different protocol named in
Upgrade, for example TLS. - 428
Precondition Required
The server requires the request to be conditional (an
If-Matchheader) to prevent lost updates. - 429
Too Many Requests
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 Large
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 Reasons
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 Error
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 Implemented
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 Gateway
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 Unavailable
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 Timeout
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 Supported
The server refuses to support the HTTP version used in the request.
- 506
Variant Also Negotiates
A configuration error in transparent content negotiation. Essentially unused.
- 507
Insufficient Storage
The server cannot store the representation.
- 508
Loop Detected
Infinite loop while processing a request with
Depth: infinity. - 510
Not Extended (obsoleted)
Historic; the underlying extension framework was never adopted.
- 511
Network Authentication Required
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