Comprehensive reference for http status codes reference covering essential concepts, practical examples, and production best practices.
HTTP status codes are the foundation of communication between clients and servers in web applications. When a request fails, a service doesn’t respond, or a client needs to adapt behavior based on server feedback, HTTP status codes provide the definitive answer. This reference compiles the complete set of status codes, their precise meanings, and the real-world nuances that distinguish correct implementation from just “good enough.”
Use when: the server is processing a request and needs to inform the client of intermediate steps, often before sending the final response.
100 Continue: Client should continue sending data. Sent after Expect: 100-continue in the request header.101 Switching Protocols: Server is switching to a new protocol (e.g., WebSocket upgrade).102 Processing: Server is processing the request but hasn't sent a final response.Common usage:
POST /upload HTTP/1.1
Host: api.example.com
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="large.zip"
Content-Type: application/zip
[Binary data...]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
The client sends the Expect: 100-continue header, and the server responds HTTP/1.1 100 Continue before receiving the full request body.
Sharp edges:
Expect: 100-continue, the server may not send 100 Continue, and the client assumes the request is complete after sending the headers.101 Switching Protocols must be sent before the final response body. The Upgrade header is required:HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRjOGO7BYoN8p9u52SjC366K
102 Processing is not widely used. Clients must handle it correctly—many assume the final response is the only response.Use when: the request was successfully received, understood, and processed.
200 OK: Standard success. Response body contains the result.201 Created: Resource was created. Response body contains the new resource.202 Accepted: Request accepted for processing, but not yet completed.204 No Content: Request processed, but no response body.206 Partial Content: Partial content returned (e.g., for range requests).Common patterns:
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "Alice",
"email": "[email protected]"
}
HTTP/1.1 201 Created
Location: /users/123
Content-Type: application/json
Content-Length: 125
{
"id": 123,
"name": "Alice",
"email": "[email protected]",
"created_at": "2023-10-05T12:00:00Z"
}
Key points:
Location header is required for 201 Created.Location header to retrieve the created resource.Content-Type of the response body must match the request body format.POST /jobs HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"type": "report",
"params": { "start": "2023-01-01", "end": "2023-12-31" }
}
HTTP/1.1 202 Accepted
Content-Type: application/json
Content-Length: 102
{
"job_id": "job-98765",
"status": "queued",
"message": "Job received and queued for processing."
}
Sharp edges:
202 Accepted does not imply the job is complete. The client must poll GET /jobs/job-98765 or use webhooks.null or {}, but it's not required.201 Created for async jobs, but 202 Accepted is the correct choice.GET /video.mp4 HTTP/1.1
Host: media.example.com
Range: bytes=100000-199999
HTTP/1.1 206 Partial Content
Content-Range: bytes 100000-199999/500000
Content-Length: 100000
Content-Type: video/mp4
[100,000 bytes of video data]
Key points:
Content-Range header is mandatory.206 can be used with If-Range to avoid redundant downloads.Use when: the client needs to follow a new location to complete the request.
301 Moved Permanently: The resource has moved permanently.302 Found: Temporary redirect.303 See Other: Redirection after POST, typically to a GET.304 Not Modified: Client can use cached response.307 Temporary Redirect: Same as 302, but preserves request method.308 Permanent Redirect: Same as 301, but preserves request method.Critical distinctions:
GET /old-page.html HTTP/1.1
Host: example.com
HTTP/1.1 301 Moved Permanently
Location: /new-page.html
Cache-Control: public, max-age=3600
HTTP/1.1 302 Found
Location: /new-page.html
Sharp edges:
301 means the client should cache the redirect forever (unless overridden).302 does not require caching; clients may re-check the original URL.303 See Other is used after POST to redirect to a GET page (e.g., “Create User” → “User Profile”):POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{ "name": "Bob" }
HTTP/1.1 303 See Other
Location: /users/456
Content-Type: text/html
<h1>User created: Bob</h1>
307 and 308 preserve the request method and body:POST /upload HTTP/1.1
Host: example.com
Content-Length: 1024
[Binary data...]
HTTP/1.1 308 Permanent Redirect
Location: https://files.example.com/upload
The client resends the POST request to https://files.example.com/upload with the same body and headers.
Key points:
307 and 308 are not the same as 302 and 301—the method and body are preserved.303 to avoid double-submissions after POST.304 Not Modified is used with If-Modified-Since or If-None-Match:GET /blog/post/123 HTTP/1.1
Host: blog.example.com
If-Modified-Since: Wed, 04 Oct 2023 12:00:00 GMT
HTTP/1.1 304 Not Modified
ETag: "abc123"
Last-Modified: Wed, 04 Oct 2023 12:00:00 GMT
The client uses the cached response and does not receive the body.
Use when: the client made a malformed request or provided invalid data.
400 Bad Request: General error in request structure.401 Unauthorized: Authentication required.403 Forbidden: Client has access, but not allowed.404 Not Found: Resource does not exist.405 Method Not Allowed: Requested method is not supported.409 Conflict: Request conflicts with current state.410 Gone: Resource is permanently gone.422 Unprocessable Entity: Semantic errors in request body (e.g., validation failures).Critical patterns:
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "",
"email": "invalid-email"
}
HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 123
{
"error": "Validation failed",
"details": [
{
"field": "name",
"message": "Name is required"
},
{
"field": "email",
"message": "Email is invalid"
}
]
}
Sharp edges:
400 is the default for any client error—use it when you don’t know the exact failure.details object in the response body for better debugging.422 Unprocessable Entity for validation failures:HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"errors": [
{
"field": "dob",
"code": "invalid_date",
"message": "Date must be in YYYY-MM-DD format"
},
{
"field": "skills",
"code": "min_length",
"message": "At least 2 skills required"
}
]
}
GET /api/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer abc123xyz
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api.example.com", error="invalid_token", error_description="The access token is expired"
Content-Type: application/json
{
"error": "invalid_token",
"error_description": "The access token is expired",
"expires_in": 3600
}
Key points:
WWW-Authenticate header is required.Bearer tokens are common, but Basic authentication uses:WWW-Authenticate: Basic realm="API"
GET /users/9999 HTTP/1.1
Host: api.example.com
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "User not found",
"id": 9999,
"message": "No user with ID 9999 exists."
}
Sharp edges:
404 should be returned even when the resource exists but is inactive (e.g., soft-deleted).410 Gone when a resource is permanently removed:HTTP/1.1 410 Gone
Content-Type: application/json
{
"error": "Resource permanently removed",
"message": "User 9999 was deleted and will not be restored."
}
Use when: the server encountered an error while processing the request.
500 Internal Server Error: General server error.501 Not Implemented: Server lacks functionality to handle the request.502 Bad Gateway: Backend server failed to respond.503 Service Unavailable: Server is temporarily overloaded.504 Gateway Timeout: Backend took too long to respond.Common patterns:
POST /orders HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"items": [ { "id": 1, "quantity": 5 } ]
}
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 187
{
"error": "Internal server error",
"details": {
"timestamp": "2023-10-05T12:05:30Z",
"trace_id": "a1b2c3d4",
"error_code": "DB-100",
"message": "Failed to save order to database"
},
"debug": {
"sql": "INSERT INTO orders ...",
"params": [1, 5],
"error": "SQLSTATE[HY000]: General error: 1213 Deadlock found when trying to get lock"
}
}
Key points:
trace_id or request_id in the response body for tracing logs.502 Bad Gateway when a proxy (e.g., NGINX, API Gateway) receives a failure from a backend:HTTP/1.1 502 Bad Gateway
Content-Type: text/html
<h1>502 Bad Gateway</h1>
<p>The upstream server failed to respond.</p>
HTTP/1.1 503 Service Unavailable
Retry-After: 60
Content-Type: application/json
{
"error": "Service maintenance",
"scheduled_end": "2023-10-06T05:00:00Z",
"message": "Database is being upgraded. Please try again in 1 minute."
}
Sharp edges:
Retry-After header is critical for clients to implement exponential backoff.503 is often used during rolling deployments, zero-downtime updates, or when scaling out.| Code | Meaning | Use Case |
|---|---|---|
| 200 | OK | Standard success |
| 201 | Created | Resource created |
| 202 | Accepted | Asynchronous processing |
| 204 | No Content | Success, no body |
| 206 | Partial Content | Range requests |
| 301 | Moved Permanently | Permanent redirect |
| 302 | Found | Temporary redirect |
| 303 | See Other | After POST |
| 304 | Not Modified | Cached response |
| 400 | Bad Request | General client error |
| 401 | Unauthorized | Authentication required |
| 403 | Forbidden | Access denied |
| 404 | Not Found | Resource missing |
| 409 | Conflict | State conflict |
| 410 | Gone | Resource permanently removed |
| 422 | Unprocessable Entity | Validation errors |
| 500 | Internal Server Error | General server error |
| 502 | Bad Gateway | Backend failure |
| 503 | Service Unavailable | Server overloaded |
| 504 | Gateway Timeout | Backend took too long |
This reference is for engineers who need to implement, debug, and optimize HTTP interactions—precisely, not approximately.
This page was rewritten on 10 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy