The Ultimate Guide to HTTP Status Codes
HTTP status codes indicate the result of a web server's request processing. They are grouped into five classes, each representing a different category of response. Understanding these codes is essential for web developers, API designers, system administrators, and anyone working with web technologies. Status codes allow clients — whether browsers, mobile apps, or other servers — to understand what happened with their request and how to proceed.
How HTTP Status Codes Work
When a client sends an HTTP request to a server, the server responds with a three-digit status code followed by a human-readable reason phrase. The first digit of the status code defines the class of the response. The remaining two digits do not have any specific categorization role but provide granularity within each class. Status codes are defined by the Internet Assigned Numbers Authority (IANA) based on specifications published in RFC documents. As of 2025, there are over 70 officially registered HTTP status codes, though only about 30-40 are in common use.
Quick Reference
| Class | Category | Meaning |
|---|---|---|
| 1xx | Informational | Request received, continuing processing |
| 2xx | Success | Request received, understood, and accepted |
| 3xx | Redirection | Further action needed to complete the request |
| 4xx | Client Error | Request has bad syntax or cannot be fulfilled |
| 5xx | Server Error | Server failed to fulfill a valid request |
1xx - Informational
These codes indicate that the server has received the request headers and the client should continue to send the body, or that the server is switching to a different protocol. These are provisional responses with no actual body content.
| Code | Name | Description |
|---|---|---|
| 100 | Continue | Server received headers, client should continue sending body |
| 101 | Switching Protocols | Server is switching protocols (e.g., upgrading to WebSocket) |
| 102 | Processing | Server is processing the request but no response yet (WebDAV) |
| 103 | Early Hints | Preload resources while server prepares response, used for performance optimization |
The 100 Continue status is often used in conjunction with the Expect: 100-continue request header. When a client sends this header, it awaits confirmation before sending a large payload. This prevents wasted bandwidth when the server is going to reject the request based on headers alone.
101 Switching Protocols is the cornerstone of WebSocket connections. When a client sends an Upgrade: websocket header, the server responds with 101 to confirm the protocol switch from HTTP to WebSocket, enabling real-time bidirectional communication.
103 Early Hints is a relatively new addition (RFC 8297) that allows servers to send hints to the browser about critical resources (CSS, JavaScript, fonts) that will be needed by the final response. This enables the browser to start preloading these resources before the full response is ready, improving perceived performance.
2xx - Success
These codes indicate that the client's request was successfully received, understood, and accepted. This is the category every developer hopes to see.
| Code | Name | Description |
|---|---|---|
| 200 | OK | Standard success response for GET, POST, PUT requests |
| 201 | Created | Resource created successfully, typically in response to POST |
| 202 | Accepted | Request accepted for processing but not yet completed |
| 203 | Non-Authoritative Info | Response from a third-party source, not the origin server |
| 204 | No Content | Success, but no response body to return |
| 205 | Reset Content | Tells browser to clear the current form/document |
| 206 | Partial Content | Partial resource returned, used for range requests and resumable downloads |
| 207 | Multi-Status | Multiple status codes for multiple resources (WebDAV) |
| 208 | Already Reported | Resource was already reported (WebDAV) |
200 OK is the most common status code. It indicates that the request succeeded and the response body contains the requested data. For GET requests, the body contains the resource representation. For POST requests, it contains the result of the action.
201 Created should be returned when a new resource is created as a result of a POST or PUT request. The response should include a Location header pointing to the newly created resource's URL. For example, after creating a new user, return 201 Created with the user's profile URL in the Location header.
204 No Content is useful for DELETE requests or PUT updates where the response body is empty. It tells the client that the operation succeeded but there is nothing to return. The browser should not change its current document view.
3xx - Redirection
These codes indicate that the client needs to take additional action to complete the request, usually by following a redirect to a different URL.
| Code | Name | Description |
|---|---|---|
| 300 | Multiple Choices | Multiple possible representations, client should choose |
| 301 | Moved Permanently | Resource has a new permanent URL, update bookmarks |
| 302 | Found | Temporary redirect, keep using original URL in future |
| 303 | See Other | Redirect to a different URL using GET method |
| 304 | Not Modified | Resource not modified, use cached version |
| 307 | Temporary Redirect | Temporary redirect preserving HTTP method |
| 308 | Permanent Redirect | Permanent redirect preserving HTTP method |
The distinction between 301 and 302 is critical for SEO. Search engines treat 301 redirects as permanent, transferring the original URL's ranking power to the new URL. A 302 redirect does not transfer SEO value because the original URL is expected to return.
304 Not Modified is used in conjunction with conditional request headers like If-Modified-Since or If-None-Match (ETags). When the client has a cached version of a resource, it can ask the server whether the resource has changed. If it has not, the server returns 304 with no body, saving bandwidth on both sides.
307 and 308 preserve the HTTP method used in the original request, unlike 302 and 301 which may change POST to GET. This distinction matters for API endpoints where preserving the request method is important.
4xx - Client Error
These codes indicate that the client sent a problematic request. The error is on the client side — the server is working correctly.
| Code | Name | Description |
|---|---|---|
| 400 | Bad Request | Invalid request syntax or parameters |
| 401 | Unauthorized | Authentication is required or has failed |
| 402 | Payment Required | Reserved for future use, rarely implemented |
| 403 | Forbidden | Client authenticated but does not have permission |
| 404 | Not Found | The requested resource does not exist |
| 405 | Method Not Allowed | The HTTP method is not supported for this URL |
| 406 | Not Acceptable | Cannot generate response matching Accept headers |
| 407 | Proxy Authentication | Must authenticate with a proxy first |
| 408 | Request Timeout | Server timed out waiting for the request |
| 409 | Conflict | Request conflicts with current server state |
| 410 | Gone | Resource permanently deleted, no forwarding address |
| 411 | Length Required | Content-Length header is required |
| 412 | Precondition Failed | Conditional request headers evaluated to false |
| 413 | Payload Too Large | Request body exceeds server limits |
| 414 | URI Too Long | URL exceeds server's maximum allowed length |
| 415 | Unsupported Media Type | Content-Type not supported by the server |
| 416 | Range Not Satisfiable | Range header cannot be satisfied |
| 417 | Expectation Failed | Expect header cannot be satisfied |
| 422 | Unprocessable Entity | Request body is syntactically correct but semantically invalid |
| 423 | Locked | Resource is locked (WebDAV) |
| 424 | Failed Dependency | Request failed because another request failed (WebDAV) |
| 426 | Upgrade Required | Client should switch to a different protocol |
| 428 | Precondition Required | Origin server requires the request to be conditional |
| 429 | Too Many Requests | Client has exceeded rate limits |
| 431 | Request Header Too Large | Headers exceed maximum size |
| 451 | Unavailable For Legal Reasons | Resource blocked due to legal demands |
400 Bad Request is the catch-all for client errors. Use it when the server cannot process the request due to malformed syntax, invalid query parameters, or a malformed request body. Always include a descriptive error message in the response body to help clients fix the issue.
401 Unauthorized is returned when the client has not provided valid authentication credentials. The response should include a WWW-Authenticate header indicating the authentication scheme (Basic, Bearer, Digest, etc.) the server expects.
403 Forbidden differs from 401 in that the client is authenticated but does not have sufficient permissions. For example, a regular user trying to access an admin endpoint should get 403, not 401.
404 Not Found is the most well-known HTTP status code. It indicates the server cannot find the requested resource. Be careful not to reveal whether the resource exists but is hidden — returning 404 for both non-existent and forbidden resources is a common security practice.
409 Conflict is useful for REST APIs when there is a version conflict. For example, when a PUT request updates a resource that has been modified by another user since the client last fetched it.
429 Too Many Requests is essential for API rate limiting. It should include a Retry-After header indicating how long the client should wait before making another request.
5xx - Server Error
These codes indicate that the server encountered an error while processing a valid request. The problem is on the server side.
| Code | Name | Description |
|---|---|---|
| 500 | Internal Server Error | Generic server error, no specific details available |
| 501 | Not Implemented | Server does not support the requested functionality |
| 502 | Bad Gateway | Upstream server returned an invalid response |
| 503 | Service Unavailable | Server temporarily unavailable (overloaded or down) |
| 504 | Gateway Timeout | Upstream server did not respond in time |
| 505 | HTTP Version Not Supported | Server does not support the HTTP protocol version used |
| 506 | Variant Also Negotiates | Server configuration error in content negotiation |
| 507 | Insufficient Storage | Server cannot store the representation (WebDAV) |
| 508 | Loop Detected | Server detected an infinite loop (WebDAV) |
| 509 | Bandwidth Limit Exceeded | Not an official status, used by some Apache modules |
| 510 | Not Extended | Further extensions are required for the request |
| 511 | Network Authentication Required | Client must authenticate to access the network |
500 Internal Server Error is the catch-all for server-side failures. It should never be returned for invalid client requests — those should use 4xx codes. A 500 response indicates something went wrong in the server's processing logic.
502 Bad Gateway typically occurs when a proxy or load balancer receives an invalid response from an upstream server. For example, if an application server crashes or returns a malformed response, the reverse proxy returns 502 to the client.
503 Service Unavailable is used when the server is temporarily overloaded or down for maintenance. Include a Retry-After header so clients and crawlers know when to retry. This is commonly seen during deployment windows or traffic spikes.
504 Gateway Timeout occurs when one server in a chain (e.g., a reverse proxy talking to an application server) does not receive a timely response from another server. The default timeout is typically 30-120 seconds depending on the infrastructure.
Status Code Usage Guide
| Scenario | Status Code |
|---|---|
| Successful GET request | 200 |
| Successful POST (created) | 201 |
| Successful DELETE | 204 |
| Form validation fails | 422 |
| User not logged in | 401 |
| User lacks permission | 403 |
| Resource not found | 404 |
| Rate limit exceeded | 429 |
| Server crash | 500 |
| API endpoint not implemented yet | 501 |
| Temporary maintenance | 503 |
Best Practices for Using HTTP Status Codes
Always use the most specific status code that applies to your situation. Returning a generic 500 error when a 503 or 504 is more appropriate makes debugging harder for API consumers. Include descriptive error messages and unique error identifiers in your response bodies to help with debugging. For REST APIs, also consider including a machine-readable error code that clients can programmatically handle. Finally, ensure your error responses respect the content type requested through content negotiation — return JSON for API clients and HTML for browser-based error pages.
Use the HTTP Status Code Reference tool for quick lookups whenever you need to recall the meaning or proper usage of any HTTP status code.