Quick Reference
1xx — Informational
Provisional responses. The server has received the request and the client should continue. Rarely seen directly — mostly used internally by HTTP clients and servers.
| Code | Name | Meaning | Common Scenario |
|---|---|---|---|
100 |
Continue | Server received request headers; client should proceed with the body | Large file uploads using Expect: 100-continue |
101 |
Switching Protocols | Server is switching to the protocol requested by the client | WebSocket handshake upgrade from HTTP |
102 |
Processing | Server has received and is processing the request; no response yet | WebDAV long-running operations |
103 |
Early Hints | Allows server to send response headers early while preparing the full response | Preloading CSS/JS resources before HTML is ready |
2xx — Success
The request was successfully received, understood, and accepted. The most important class for API design.
| Code | Name | Meaning | Common Scenario |
|---|---|---|---|
200 |
OK | Request succeeded. Response body contains the result. | GET request returns data; POST form submitted successfully |
201 |
Created | Request succeeded and a new resource was created. | POST to create a new user, record, or file; include Location header |
202 |
Accepted | Request accepted for processing, but processing is not complete. | Async operations — job queued, email will be sent |
203 |
Non-Authoritative Information | Response is from a proxy or cache, not the origin server. | CDN or proxy returning modified metadata |
204 |
No Content | Request succeeded. No response body. | DELETE succeeded; PUT/PATCH with no body to return |
205 |
Reset Content | Request succeeded. Client should reset the document view. | Form submitted — clear the form fields |
206 |
Partial Content | Server is delivering only part of the resource (range request). | Resumable downloads, video streaming with Range header |
207 |
Multi-Status | Response body contains multiple status codes for multiple operations. | WebDAV batch operations |
208 |
Already Reported | Members of a DAV binding already enumerated in a previous reply. | WebDAV — avoids infinite loops in collection listings |
226 |
IM Used | Server fulfilled a GET using instance manipulation (delta encoding). | HTTP delta encoding (RFC 3229) — rare in practice |
200 for successful GET/PUT/PATCH, 201 for successful POST that creates a resource, 204 for successful DELETE. Returning 200 for everything is a common anti-pattern that breaks API clients.
3xx — Redirection
Further action must be taken to complete the request. The Location header specifies where to go. Understanding the difference between 301 and 302 is critical for SEO and API design.
| Code | Name | Method After Redirect | Permanent? | Common Scenario |
|---|---|---|---|---|
300 |
Multiple Choices | Any | — | Multiple representations available (e.g., language selection) |
301 |
Moved Permanently | GET (browsers change POST → GET) | Yes — cached | HTTP → HTTPS redirect; domain change; URL restructure |
302 |
Found | GET (browsers change POST → GET) | No | Temporary redirect; login flow redirects |
303 |
See Other | Always GET | No | After POST/PUT/DELETE — redirect to result page (PRG pattern) |
304 |
Not Modified | — | — | Conditional GET — resource unchanged, use cached version |
307 |
Temporary Redirect | Same method preserved | No | Temporary redirect without changing method (POST stays POST) |
308 |
Permanent Redirect | Same method preserved | Yes — cached | Permanent redirect without changing method |
| Use Case | Correct Code | Why |
|---|---|---|
| HTTP → HTTPS (permanent) | 301 |
Permanent, SEO passes link equity |
| Old URL → New URL (permanent) | 301 |
Cached by browsers and search engines |
| After form POST → result page | 303 |
Forces GET, prevents duplicate form submission on refresh |
| Temporary maintenance redirect | 302 or 307 |
Not cached; use 307 if POST must stay POST |
| Permanent API endpoint move | 308 |
Permanent + preserves POST/PUT method |
4xx — Client Errors
The client sent a request the server could not or will not process. The problem is on the requester’s side.
| Code | Name | Meaning | Common Scenario |
|---|---|---|---|
400 |
Bad Request | Server cannot process due to malformed syntax or invalid parameters | Invalid JSON body, missing required field, bad query param |
401 |
Unauthorized | Authentication required and has failed or not been provided | Missing or expired Bearer token; wrong API key |
402 |
Payment Required | Reserved for future use; used by some APIs for billing limits | API quota exceeded (Stripe, Twilio); account not paid |
403 |
Forbidden | Server understood the request but refuses to authorize it | Authenticated but lacking permission; IP blocked; CORS policy |
404 |
Not Found | Server cannot find the requested resource | Wrong URL; deleted resource; typo in endpoint |
405 |
Method Not Allowed | HTTP method not supported for this endpoint | POST to a GET-only endpoint; DELETE not implemented |
406 |
Not Acceptable | Server cannot produce a response matching the Accept headers |
Client requests XML but API only supports JSON |
407 |
Proxy Authentication Required | Client must authenticate with the proxy | Corporate proxy requiring credentials |
408 |
Request Timeout | Server timed out waiting for the request | Slow network; client didn’t send body in time |
409 |
Conflict | Request conflicts with current state of the resource | Duplicate username; version conflict in optimistic locking |
410 |
Gone | Resource permanently deleted; no forwarding address | Decommissioned API endpoint; deleted user account |
411 |
Length Required | Server requires Content-Length header |
POST request without Content-Length |
412 |
Precondition Failed | One or more conditions in the request headers evaluated to false | If-Match ETag mismatch; optimistic concurrency control |
413 |
Content Too Large | Request body exceeds server limits | File upload too large; Nginx client_max_body_size limit hit |
414 |
URI Too Long | URL is longer than the server is willing to process | Extremely long query string; GET used instead of POST |
415 |
Unsupported Media Type | Server refuses to accept the request’s media format | Sending text/plain to an endpoint expecting application/json |
416 |
Range Not Satisfiable | Requested range is out of bounds for the resource | Resumable download with invalid byte range |
417 |
Expectation Failed | Server cannot meet the requirements of the Expect header |
Expect: 100-continue rejected by server |
418 |
I’m a Teapot | Server refuses to brew coffee because it is a teapot (RFC 2324) | Easter egg; used by some APIs to block automated scripts |
421 |
Misdirected Request | Request directed to a server unable to respond | HTTP/2 connection reuse to wrong virtual host |
422 |
Unprocessable Content | Request well-formed but contains semantic errors | Validation failed: field values are syntactically correct but logically invalid |
423 |
Locked | Resource is locked | WebDAV — file checked out by another user |
424 |
Failed Dependency | Request failed because a previous request failed | WebDAV batch — one operation depends on another that failed |
425 |
Too Early | Server unwilling to process a request that might be replayed | TLS 0-RTT early data replay protection |
426 |
Upgrade Required | Client must switch to a different protocol | Server requires TLS; WebSocket upgrade required |
428 |
Precondition Required | Server requires the request to be conditional | API enforcing If-Match on all updates to prevent lost updates |
429 |
Too Many Requests | Client has sent too many requests in a given time period | Rate limiting; API quota; DDoS protection; check Retry-After header |
431 |
Request Header Fields Too Large | Request headers individually or collectively are too large | Too many/large cookies; oversized Authorization header |
451 |
Unavailable For Legal Reasons | Resource withheld due to legal demands | GDPR takedown; court order; government censorship |
401 Unauthorized means “you are not authenticated — send credentials.” 403 Forbidden means “I know who you are, but you don’t have permission.” Use 401 when the user is anonymous; use 403 when the user is logged in but lacks access.
5xx — Server Errors
The server failed to fulfill a valid request. The problem is on the server’s side. These are the codes that wake sysadmins up at night.
| Code | Name | Meaning | Common Scenario |
|---|---|---|---|
500 |
Internal Server Error | Generic server-side error; something went wrong | Unhandled exception in application code; PHP fatal error |
501 |
Not Implemented | Server does not support the functionality required to fulfill the request | HTTP method not supported at all (e.g., PATCH not implemented) |
502 |
Bad Gateway | Upstream server returned an invalid response | Nginx upstream (app server, PHP-FPM) is down or crashing |
503 |
Service Unavailable | Server temporarily unable to handle requests | Maintenance mode; overloaded server; health check failing; check Retry-After |
504 |
Gateway Timeout | Upstream server did not respond in time | Nginx timed out waiting for PHP-FPM or backend API; slow database query |
505 |
HTTP Version Not Supported | Server does not support the HTTP protocol version used | Client using HTTP/3 on a server that only speaks HTTP/1.1 |
506 |
Variant Also Negotiates | Content negotiation configuration error on server | Circular reference in transparent content negotiation (rare) |
507 |
Insufficient Storage | Server is unable to store the representation needed | WebDAV — disk full; quota exceeded on upload |
508 |
Loop Detected | Server detected an infinite loop processing the request | WebDAV — recursive resource binding |
510 |
Not Extended | Further extensions to the request are required | HTTP Extension Framework (RFC 2774) — extremely rare |
511 |
Network Authentication Required | Client must authenticate to gain network access | Captive portal — hotel/airport Wi-Fi login page |
500 for validation errors or business logic failures is wrong — use 400 or 422. Returning 200 OK with {"success": false} in the body is also an anti-pattern that breaks HTTP clients, monitoring tools, and caching layers.
The 15 Codes Every Sysadmin Must Know
If you only memorize these, you will handle 95% of real-world situations.
| Code | Name | One-Line Meaning | Action Required |
|---|---|---|---|
200 | OK | Everything worked | None |
201 | Created | Resource was created | None — check Location header |
204 | No Content | Success, no body | None — don’t expect a response body |
206 | Partial Content | Range request fulfilled | Continue requesting remaining ranges |
301 | Moved Permanently | URL changed forever | Update bookmarks, links, SEO |
302 | Found | Temporarily elsewhere | Follow redirect; don’t cache |
304 | Not Modified | Use your cached copy | Load from local cache |
400 | Bad Request | Your request is malformed | Check request syntax, body, params |
401 | Unauthorized | Send credentials | Add/refresh auth token |
403 | Forbidden | No permission | Check roles/ACLs; don’t retry |
404 | Not Found | Resource doesn’t exist | Check URL, ID, or query |
429 | Too Many Requests | Slow down | Implement backoff; check Retry-After |
500 | Internal Server Error | Server crashed | Check logs; fix application error |
502 | Bad Gateway | Upstream is broken | Check app server / backend health |
503 | Service Unavailable | Server overloaded or in maintenance | Check load; implement retry logic |
Debugging Guide
Check HTTP Status Codes from the Command Line
| Command | What It Shows |
|---|---|
curl -I https://example.com | Response headers only — status code is on the first line |
curl -o /dev/null -s -w "%{http_code}\n" https://example.com | Print only the status code |
curl -L -I https://example.com | Follow redirects, show all intermediate status codes |
curl -v https://example.com 2>&1 | grep "<" | Show all response headers in verbose mode |
wget --server-response -q -O /dev/null https://example.com | Show server response headers |
Nginx — Errors by Status Code
| Code | Likely Nginx Cause | Where to Look |
|---|---|---|
413 | client_max_body_size too low | nginx.conf or site config |
499 | Client closed connection before server responded | Nginx access log — not an error, check slow upstream |
502 | PHP-FPM / upstream app is down or misconfigured | /var/log/nginx/error.log |
503 | No upstream servers available; all backends unhealthy | Upstream block configuration |
504 | proxy_read_timeout / fastcgi_read_timeout exceeded | Increase timeout or fix slow backend |
FAQ
What is the difference between 401 and 403?
What is the difference between 301 and 302?
When should I use 404 vs 410?
What is the difference between 400, 422, and 500 for validation errors?
Why am I getting 502 instead of 503?
What does the Retry-After header do?
Retry-After header is sent with 429 Too Many Requests and 503 Service Unavailable responses. It tells the client how long to wait before retrying. The value can be a number of seconds (Retry-After: 120) or an HTTP date (Retry-After: Fri, 18 Apr 2026 12:00:00 GMT). Well-behaved API clients should respect this header to implement exponential backoff.