HTTP Status Codes: A Complete Reference Guide for Developers
What Are HTTP Status Codes?
Every time your browser requests a web page, downloads a file, or submits a form, the server replies with a three-digit number called an HTTP status code. This small number carries enormous meaning: it tells the client — whether that is a browser, a mobile app, or an API consumer — exactly what happened with the request.
HTTP status codes are defined in RFC 9110 (formerly RFC 7231) and are grouped into five classes based on their first digit:
| Range | Class | Purpose |
|---|---|---|
| 1xx | Informational | Request received, processing continues |
| 2xx | Success | Request successfully received and processed |
| 3xx | Redirection | Further action needed to complete the request |
| 4xx | Client Error | The request contains bad syntax or cannot be fulfilled |
| 5xx | Server Error | The server failed to fulfill a valid request |
Understanding these codes is essential for building robust web applications, debugging API integrations, and diagnosing network issues. Let's dive into each class in detail.
1xx Informational Responses
The 1xx class of status codes indicates that the server has received the request and the client should continue the process. These are rarely seen in everyday browsing but play an important role in protocol-level communication.
100 Continue
The server has received the request headers, and the client should proceed to send the request body. This is useful when a client wants to check if the server will accept a large payload before actually transmitting it. The client sends an Expect: 100-continue header, and if the server responds with 100 Continue, the client proceeds.
101 Switching Protocols
The server understands the Upgrade header sent by the client and agrees to switch to a different protocol. The most common use case is upgrading an HTTP connection to a WebSocket connection.
103 Early Hints
A relatively new status code that allows the server to send preliminary headers before the final response. This enables the browser to start preloading resources (stylesheets, scripts) while the server is still preparing the main response, improving page load performance.
2xx Success
The 2xx family is what every developer hopes to see. These codes indicate that the request was successfully received, understood, and accepted by the server.
200 OK
The most common HTTP status code. The request has succeeded, and the response body contains the requested resource. For a GET request, this means the resource has been fetched and transmitted. For a POST request, it means the action has been completed and the result is returned.
201 Created
The request has been fulfilled and a new resource has been created. This is the standard response for successful POST requests in REST APIs. The response typically includes a Location header pointing to the newly created resource.
204 No Content
The server has successfully processed the request but is not returning any content. This is commonly used for DELETE operations or PUT updates where the client does not need a response body.
206 Partial Content
The server is delivering only part of the resource due to a Range header sent by the client. This is essential for features like video streaming, resumable downloads, and pagination of large files.
| Code | Meaning | Typical Use | Has Body? |
|---|---|---|---|
| 200 | OK | GET, POST (general success) | Yes |
| 201 | Created | POST (resource created) | Yes |
| 204 | No Content | DELETE, PUT (no body needed) | No |
| 206 | Partial Content | Streaming, resumable downloads | Yes (partial) |
3xx Redirection
The 3xx codes tell the client that the requested resource has moved somewhere else. Understanding the differences between these codes is crucial for SEO, API design, and maintaining backward compatibility.
301 vs 302 vs 307 vs 308 — What's the Difference?
This is one of the most confusing areas in HTTP. The key distinction lies in two dimensions: whether the redirect is permanent or temporary, and whether the HTTP method is preserved or changed after the redirect.
| Code | Name | Permanent? | Method Preserved? | SEO Weight Transfer |
|---|---|---|---|---|
| 301 | Moved Permanently | Yes | No (may change to GET) | Yes (full) |
| 302 | Found | No | No (may change to GET) | No |
| 307 | Temporary Redirect | No | Yes | No |
| 308 | Permanent Redirect | Yes | Yes | Yes (full) |
SEO Tip: When permanently moving a page to a new URL, always use a 301redirect. Search engines will transfer the accumulated "link juice" (ranking power) from the old URL to the new one. A 302, on the other hand, signals that the move is temporary, so search engines will keep the original URL indexed.
In practice, use 301 for permanent URL changes (e.g., domain migration, URL restructuring). Use 307 for temporary redirects where you need the HTTP method (POST, PUT, DELETE) to be preserved — for example, redirecting a form submission to a temporary processing endpoint. Use 308 if you want a permanent redirect that also guarantees method preservation, which is critical for API endpoints.
4xx Client Errors
The 4xxfamily indicates that the error originated on the client side. The request was malformed, unauthorized, or pointed to a non-existent resource. These are the codes you'll encounter most frequently during development and debugging.
400 Bad Request
The server cannot process the request due to something perceived as a client error — for example, malformed JSON in the request body, invalid query parameters, or missing required fields. When building APIs, always return a descriptive error message alongside a 400 status to help consumers debug the issue.
401 Unauthorized vs 403 Forbidden
These two codes are often confused, but they have distinct meanings:
- 401 Unauthorized — The request lacks valid authentication credentials. The client has not identified itself. The solution is to log in or provide a valid token. Despite the name "Unauthorized," this code is really about authentication, not authorization.
- 403 Forbidden — The server understood the request and knows who the client is, but refuses to authorize it. The client is authenticated but does not have permission to access the resource. Re-authenticating will not help.
Common Mistake:Returning a 403 when the user is not logged in. If there's no authentication token at all, the correct response is 401. Only use 403 when the user is authenticated but lacks the necessary permissions. Also check that your JWT token hasn't expired if you're seeing unexpected 401 errors.
404 Not Found
Perhaps the most famous HTTP status code. The server cannot find the requested resource. This can mean the URL is wrong, the resource has been deleted, or the route simply does not exist. In REST APIs, a 404 should be returned when a specific resource (e.g., /api/users/9999) does not exist.
405 Method Not Allowed
The HTTP method used is not supported for the requested resource. For example, trying to send a DELETE request to an endpoint that only accepts GET and POST. The response should include an Allow header listing the permitted methods.
409 Conflict
The request conflicts with the current state of the server. Common scenarios include trying to create a resource that already exists (e.g., registering with an email that is already taken) or attempting an update that violates a concurrency constraint (optimistic locking failure).
422 Unprocessable Entity
The server understands the content type and syntax of the request, but it is unable to process the contained instructions. This is commonly used for validation errors — for instance, when the JSON is well-formed but the values fail business logic validation (e.g., an age of -5 or a date in the past for a future event).
429 Too Many Requests
The client has sent too many requests in a given time window. Rate limiting is a critical defense mechanism for APIs, protecting servers from abuse, DDoS attacks, and runaway scripts. The response typically includes a Retry-After header indicating how long the client should wait before making another request.
5xx Server Errors
The 5xxcodes mean the fault lies with the server. The client's request was valid, but the server encountered an unexpected condition that prevented it from fulfilling the request.
500 Internal Server Error
The generic catch-all server error. This typically indicates an unhandled exception, a bug in the application code, or a misconfigured server. When you see a 500 error, check your server logs immediately — the status code alone tells you nothing about the root cause.
Security Warning: Never expose stack traces or internal error details to the client in a 500 response. Return a generic message to the user and log the full error server-side. Exposing internals can reveal database structure, file paths, and dependency versions to potential attackers.
502 Bad Gateway
The server, acting as a gateway or proxy, received an invalid response from an upstream server. This commonly occurs when a reverse proxy (like Nginx) cannot reach the application server behind it, or when a load balancer forwards a request to a backend that has crashed.
503 Service Unavailable
The server is temporarily unable to handle the request, usually due to being overloaded or undergoing maintenance. Unlike a 500, a 503 implies the situation is temporary. Best practice is to include a Retry-After header so clients know when to try again.
504 Gateway Timeout
Similar to 502, but instead of an invalid response, the upstream server simply did not respond in time. This often happens when a backend service is performing a long-running operation (e.g., a complex database query) and the proxy's timeout threshold is exceeded. Solutions include increasing timeout limits, optimizing slow queries, or implementing asynchronous processing patterns.
REST API Best Practices for Status Codes
Choosing the right status code is a cornerstone of good API design. A well-designed API uses status codes consistently so that consumers can build reliable error handling without parsing error messages. Here is a recommended mapping of CRUD operations to HTTP status codes:
| Operation | HTTP Method | Success Code | Common Error Codes |
|---|---|---|---|
| Create | POST | 201 Created | 400, 409, 422 |
| Read (single) | GET | 200 OK | 404 |
| Read (list) | GET | 200 OK | 400 |
| Update (full) | PUT | 200 OK | 400, 404, 409, 422 |
| Update (partial) | PATCH | 200 OK | 400, 404, 422 |
| Delete | DELETE | 204 No Content | 404 |
Pro Tip: Always return consistent error response bodies. A standard format like { "error": { "code": "VALIDATION_ERROR", "message": "..." } } makes it much easier for API consumers to implement error handling. Use a JSON formatter to inspect and validate your API responses.
Additional guidelines for REST API status codes:
- Don't overuse 200 — returning 200 for everything (including errors) forces consumers to parse the body to determine success or failure.
- Use 422 for validation errors — distinguish between a malformed request (400) and a request that is well-formed but fails validation (422).
- Include pagination metadata in 200 responses for list endpoints — total count, page size, next/previous links.
- Return 401 before 403 — always check authentication first, then authorization.
Debugging HTTP Status Codes
When an API call returns an unexpected status code, knowing how to inspect the full request-response cycle is critical. Here are the most effective tools for debugging.
Browser DevTools — Network Tab
Open the Network tab in Chrome DevTools (F12 or Cmd+Opt+I) and reproduce the request. You can see the status code, request/response headers, timing information, and the full response body. Filter by "XHR" or "Fetch" to focus on API calls.
Using curl for Header Inspection
The curl -I command sends a HEAD request and displays only the response headers, including the status code:
For more detailed analysis, use curl -v ( verbose) to see both the request and response headers. This is invaluable for debugging authentication issues, redirect chains, and CORS problems.
Analyzing Response Headers
Response headers often contain clues about why a specific status code was returned. Key headers to look for include:
WWW-Authenticate— explains why a 401 was returned and what authentication scheme is expected.Location— indicates the redirect target for 3xx responses.Retry-After— tells you when to retry after a 429 or 503.Allow— lists permitted HTTP methods for a 405 response.
Use the HTTP Header Parser to quickly decode and analyze response headers from any HTTP request.
Look Up Status Codes with BeautiCode
Remembering what each status code means can be challenging, especially for the less common ones like 422, 451, or 511. That's why we built a dedicated HTTP Status Codes reference tool right here on BeautiCode.
With BeautiCode's HTTP Status Codes tool, you can:
- Search by code number — instantly look up any status code and see its name, description, and common use cases.
- Browse by category — filter by 1xx, 2xx, 3xx, 4xx, or 5xx to explore all codes in a given class.
- Copy for documentation — quickly grab the code and description for your API docs or error handling logic.
Combine it with our HTTP Header Parser to analyze response headers, or use the JWT Decoder to debug authentication tokens when you encounter 401 errors. Everything runs directly in your browser — no data is sent to any server.
Frequently Asked Questions
What is the difference between 401 and 403?
A 401 Unauthorizedresponse means the client has not provided valid authentication credentials — the server doesn't know who you are. A 403 Forbiddenresponse means the server knows who you are (you are authenticated) but you don't have permission to access the requested resource. Think of 401 as "please log in" and 403 as "you're logged in, but you can't access this."
Should I use 404 or 400 when a resource is not found?
Use 404 Not Found when the client is requesting a specific resource that does not exist (e.g., GET /users/9999 when user 9999 doesn't exist). Use 400 Bad Request when the request itself is malformed — for example, an invalid ID format like GET /users/abc where the ID must be numeric.
When should I return 204 vs 200 with an empty body?
Use 204 No Content when the operation was successful and there is intentionally no content to return — this is semantically clear and avoids sending an empty body. Use 200 OKwith an empty body (or minimal confirmation) only when the endpoint's contract explicitly defines a response body. For DELETE operations, 204 is the most widely accepted convention.
How do I handle rate limiting (429) in my application?
When you receive a 429 Too Many Requests response, read the Retry-After header to determine how long to wait before retrying. Implement exponential backoff — wait 1 second, then 2, then 4, and so on — rather than retrying immediately. Also consider queuing requests client-side and respecting the X-RateLimit-Remaining header to proactively slow down before hitting the limit.
What causes a 502 Bad Gateway error and how do I fix it?
A 502 Bad Gateway means a proxy or load balancer received an invalid response from an upstream server. Common causes include: the backend application has crashed or is not running, the backend is listening on the wrong port, network connectivity issues between the proxy and backend, or the backend returned a malformed HTTP response. To fix it, check your application logs, verify the backend process is running, ensure the proxy configuration points to the correct upstream address, and confirm there are no firewall rules blocking internal traffic.
Related Articles
How to Generate Secure Passwords in 2026: A Complete Guide
Learn why strong passwords matter and how to generate secure passwords using entropy, length, and complexity. Includes practical tips and free tools.
2026-03-23 · 8 min readData FormatsJSON vs YAML: When to Use What — A Developer's Guide
Compare JSON and YAML formats with syntax examples, pros and cons, and use case recommendations for APIs, configs, and CI/CD pipelines.
2026-03-23 · 10 min read