HTTP Status Codes
Searchable HTTP status code reference including the proxy-specific codes - 499, 502, 504, 52x - that actually show up in production incidents.
Result
Status classes
| Class | Meaning | Description |
|---|---|---|
| 1xx | Informational | Request received, processing continues. |
| 2xx | Success | The request was received, understood and accepted. |
| 3xx | Redirection | Further action needed to complete the request. |
| 4xx | Client error | The request is faulty - fixing it is the client's job. |
| 5xx | Server error | The request was valid; the server failed to fulfil it. |
Codes (40)
| Code | Name | What it means in practice |
|---|---|---|
| 100 | Continue | Client may send the request body. Used with Expect: 100-continue. |
| 101 | Switching Protocols | Upgrade accepted - WebSocket handshake. |
| 103 | Early Hints | Preload hints before the final response. |
| 200 | OK | Standard success. |
| 201 | Created | Resource created; Location header should point at it. |
| 204 | No Content | Success with an empty body. Common for DELETE and captive-portal probes. |
| 206 | Partial Content | Range request satisfied - resumable downloads and video seeking. |
| 301 | Moved Permanently | Permanent redirect. Cached aggressively - hard to undo. |
| 302 | Found | Temporary redirect; method may change to GET. Prefer 307. |
| 304 | Not Modified | Cache validation succeeded; no body sent. |
| 307 | Temporary Redirect | Temporary, method and body preserved. |
| 308 | Permanent Redirect | Permanent, method and body preserved. |
| 400 | Bad Request | Malformed syntax. Often an oversized header or bad JSON. |
| 401 | Unauthorized | Authentication required or failed - it means unauthenticated. |
| 403 | Forbidden | Authenticated but not permitted, or blocked by a WAF. |
| 404 | Not Found | No resource at this path. |
| 405 | Method Not Allowed | Wrong verb - frequently a POST to a GET-only route. |
| 408 | Request Timeout | Client took too long to send the request. |
| 409 | Conflict | State conflict, such as a concurrent update. |
| 410 | Gone | Deliberately removed and will not return. |
| 413 | Payload Too Large | Body exceeds server limit - nginx client_max_body_size. |
| 414 | URI Too Long | Usually a runaway query string. |
| 418 | I'm a teapot | RFC 2324 joke code, occasionally used to fingerprint bots. |
| 421 | Misdirected Request | Connection reused for a host this server does not serve - TLS/SNI coalescing. |
| 422 | Unprocessable Content | Syntactically valid, semantically wrong - validation failures. |
| 425 | Too Early | TLS early data rejected to avoid replay. |
| 429 | Too Many Requests | Rate limited. Honour the Retry-After header. |
| 431 | Request Header Fields Too Large | Header block too big - often oversized cookies. |
| 451 | Unavailable For Legal Reasons | Blocked by legal demand. |
| 499 | Client Closed Request | nginx-specific: client gave up before the response. |
| 500 | Internal Server Error | Unhandled application error. Check application logs, not the proxy. |
| 501 | Not Implemented | Method not supported at all. |
| 502 | Bad Gateway | Upstream returned something invalid, or is not listening. |
| 503 | Service Unavailable | Temporarily overloaded or in maintenance. |
| 504 | Gateway Timeout | Upstream did not answer in time - the proxy timeout fired. |
| 507 | Insufficient Storage | Server out of space. |
| 508 | Loop Detected | Infinite redirect or recursion. |
| 521 | Web Server Is Down | Cloudflare-specific: origin refused the connection. |
| 522 | Connection Timed Out | Cloudflare-specific: origin did not complete the TCP handshake. |
| 525 | SSL Handshake Failed | Cloudflare-specific: TLS negotiation with the origin failed. |
About HTTP Status Codes
The status code is the first piece of evidence in almost every web incident. This reference includes the non-standard codes that real infrastructure emits - nginx 499, Cloudflare 52x - because those are the ones missing from most tables when you need them.
Choosing codes for an API
Use 400 for malformed syntax and 422 for a well-formed request that fails validation; the distinction tells a client whether retrying with the same body could ever work. Use 409 for a state conflict, 429 with Retry-After for rate limiting, and 503 only for genuine unavailability. Return 201 with a Location header on creation, and 204 with no body on deletion. Above all, never return 200 with an error in the body — it defeats every monitor, cache and retry policy between you and the client.
401 versus 403
401 means unauthenticated: no valid credentials were presented, and the response should include a WWW-Authenticate challenge. 403 means authenticated but not permitted - or blocked by policy such as a WAF or geo rule. The names are historically backwards, which is why the distinction is worth stating explicitly in code review.
Common use cases
- Triaging an outage from a load balancer log.
- Choosing the correct code for an API you are designing.
- Explaining to a client why a 301 cannot simply be reverted.
Edge cases and gotchas
- 301 and 308 are cached by browsers, sometimes indefinitely. Test redirects with 302 or 307 first.
- A 200 response with an error message in the body defeats every monitoring system you own.