HTTP Status Codes: Complete Reference Guide

· 12 min read

Table of Contents

What Are HTTP Status Codes?

HTTP status codes are three-digit numbers returned by a server in response to a client's request. They indicate whether the request was successful, redirected, or resulted in an error. Every time your browser loads a page, calls an API, or submits a form, the server responds with a status code.

Think of status codes as the server's way of communicating what happened with your request. Just like a traffic light tells you whether to stop or go, status codes tell your application whether to proceed, retry, or handle an error.

Status codes are grouped into five categories based on their first digit:

Quick reference: Use our HTTP Status Codes Lookup tool to quickly check any status code and see detailed explanations with examples.

How Status Codes Work

When a client (like your browser or an API client) makes an HTTP request, the server processes it and returns a response. This response always includes a status code in the first line, followed by headers and an optional body.

Here's what a typical HTTP response looks like:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1234

{"status": "success", "data": {...}}

The status code appears right after the HTTP version. In this example, 200 OK tells the client that the request succeeded.

Status codes serve multiple purposes:

1xx Informational

Informational status codes indicate that the server has received the request and is continuing to process it. These are provisional responses and are rarely seen in everyday web browsing, but they're important for certain protocols and optimizations.

100 Continue

The server received the request headers and the client should proceed to send the body. This is used with large uploads where the client sends an Expect: 100-continue header to check if the server will accept the request before sending the full payload.

This optimization prevents wasting bandwidth on requests that will be rejected. For example, if you're uploading a 500MB video file, you don't want to send all that data only to find out the server will reject it due to authentication failure.

POST /upload HTTP/1.1
Host: api.example.com
Content-Length: 524288000
Expect: 100-continue

// Server responds with 100 Continue
// Client then sends the request body

101 Switching Protocols

The server agrees to switch protocols as requested by the client. Most commonly seen when upgrading from HTTP to WebSocket using the Upgrade: websocket header.

WebSockets enable real-time, bidirectional communication between client and server, which is essential for chat applications, live updates, and collaborative tools.

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade

// Server responds with 101 Switching Protocols

103 Early Hints

This relatively new status code lets the server send preliminary headers before the final response. It's often used to start preloading resources like CSS, fonts, and JavaScript files while the server is still preparing the main response.

Early Hints can significantly improve page load times by allowing browsers to start downloading critical resources earlier in the page load process.

Pro tip: Most developers will never need to handle 1xx codes directly. They're typically managed by web servers and HTTP libraries automatically. Focus your error handling on 4xx and 5xx codes instead.

2xx Success

Success codes are what you want to see. They indicate that the request was received, understood, and accepted successfully. Different 2xx codes provide nuanced information about exactly how the request was processed.

200 OK

The standard success response. The request succeeded and the response body contains the requested data. This is the most common status code on the web.

Use 200 OK for successful GET requests that return data, successful POST requests that return created resource data, and successful PUT/PATCH requests that return updated resource data.

GET /api/users/123 HTTP/1.1

HTTP/1.1 200 OK
Content-Type: application/json

{"id": 123, "name": "John Doe", "email": "[email protected]"}

201 Created

A new resource was successfully created. This is the appropriate response for POST requests that create new resources. The response should include a Location header pointing to the newly created resource.

POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "Jane Smith", "email": "[email protected]"}

HTTP/1.1 201 Created
Location: /api/users/124
Content-Type: application/json

{"id": 124, "name": "Jane Smith", "email": "[email protected]"}

202 Accepted

The request has been accepted for processing, but processing has not been completed. This is useful for asynchronous operations where the server queues the request for later processing.

Common use cases include batch processing, email sending, video encoding, and other long-running operations that shouldn't block the HTTP response.

204 No Content

The request succeeded, but there's no content to return. This is commonly used for DELETE requests or PUT/PATCH requests where the client doesn't need the updated resource returned.

Using 204 No Content instead of 200 OK with an empty body saves bandwidth and clearly communicates intent.

DELETE /api/users/123 HTTP/1.1

HTTP/1.1 204 No Content

206 Partial Content

The server is delivering only part of the resource due to a range header sent by the client. This enables resumable downloads and video streaming where the client requests specific byte ranges.

Video players use this extensively to allow seeking to different parts of a video without downloading the entire file first.

Status Code Name When to Use
200 OK Standard success response with content
201 Created Resource successfully created
202 Accepted Request queued for async processing
204 No Content Success with no response body needed
206 Partial Content Returning requested byte range

3xx Redirection

Redirection codes indicate that the client needs to take additional action to complete the request. These are crucial for URL management, SEO, and maintaining backward compatibility when resources move.

301 Moved Permanently

The resource has permanently moved to a new URL specified in the Location header. Browsers and search engines should update their records to use the new URL.

This is the go-to status code for permanent redirects. Search engines will transfer the SEO value from the old URL to the new one, and browsers will cache the redirect.

GET /old-page HTTP/1.1

HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page

Pro tip: Use 301 redirects when you've permanently moved content. Use 302 for temporary moves. Getting this wrong can hurt your SEO, as search engines treat them very differently.

302 Found (Temporary Redirect)

The resource temporarily resides at a different URL. The client should continue to use the original URL for future requests. Search engines won't transfer SEO value with this redirect.

Common use cases include A/B testing, maintenance pages, and temporary promotional pages.

303 See Other

The response to the request can be found at another URL using GET. This is commonly used after POST requests to redirect to a result page, preventing duplicate form submissions if the user refreshes.

This implements the Post/Redirect/Get pattern, which is a best practice for web forms.

304 Not Modified

The resource hasn't been modified since the version specified in the request headers (If-Modified-Since or If-None-Match). The client can use its cached version.

This dramatically reduces bandwidth usage and improves performance by avoiding unnecessary data transfer when content hasn't changed.

307 Temporary Redirect

Similar to 302, but guarantees that the request method won't change when redirected. If the original request was POST, the redirected request will also be POST.

308 Permanent Redirect

Similar to 301, but guarantees that the request method won't change. This is the modern, more precise version of 301 for APIs and applications that need strict method preservation.

4xx Client Errors

Client error codes indicate that the request contains bad syntax or cannot be fulfilled due to client-side issues. These errors mean the client needs to modify the request before retrying.

400 Bad Request

The server cannot process the request due to malformed syntax, invalid request message framing, or deceptive request routing. This is a generic error for requests that don't fit other 4xx categories.

Common causes include malformed JSON, missing required fields, invalid data types, or requests that violate API constraints.

POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "John", "email": "not-an-email"}

HTTP/1.1 400 Bad Request
Content-Type: application/json

{"error": "Invalid email format"}

401 Unauthorized

Authentication is required and has failed or hasn't been provided. Despite the name, this actually means "unauthenticated" – the client needs to provide valid credentials.

The response should include a WWW-Authenticate header indicating the authentication method required.

GET /api/protected-resource HTTP/1.1

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"

{"error": "Authentication required"}

403 Forbidden

The server understood the request but refuses to authorize it. Unlike 401, authentication won't help – the client doesn't have permission to access this resource.

Use this when a user is authenticated but doesn't have the necessary permissions, or when access is restricted by IP address, rate limiting, or other policies.

404 Not Found

The most famous status code. The server can't find the requested resource. This could mean the URL is wrong, the resource was deleted, or it never existed.

For APIs, return 404 when a specific resource ID doesn't exist. For websites, show a helpful 404 page with navigation options and search functionality.

Quick tip: Don't return 404 for authorization failures. Use 403 or 404 strategically based on whether you want to reveal that a resource exists. For security-sensitive resources, 404 can prevent information disclosure.

405 Method Not Allowed

The request method is not supported for the requested resource. For example, trying to POST to a read-only endpoint or DELETE on a resource that doesn't support deletion.

The response must include an Allow header listing the valid methods.

DELETE /api/users HTTP/1.1

HTTP/1.1 405 Method Not Allowed
Allow: GET, POST, PUT

{"error": "DELETE method not supported"}

408 Request Timeout

The server timed out waiting for the request. The client took too long to send the complete request.

409 Conflict

The request conflicts with the current state of the server. Common in scenarios like trying to create a resource that already exists, or updating a resource that has been modified by another request.

This is particularly important for APIs that need to handle concurrent updates and maintain data consistency.

410 Gone

The resource is permanently gone and won't be available again. Unlike 404, this indicates intentional removal. Use this when you want to explicitly communicate that a resource was deleted and won't return.

413 Payload Too Large

The request entity is larger than the server is willing or able to process. Common when uploading files that exceed size limits.

415 Unsupported Media Type

The server refuses to accept the request because the payload format is not supported. For example, sending XML when the API only accepts JSON.

422 Unprocessable Entity

The request was well-formed but contains semantic errors. This is commonly used for validation errors where the syntax is correct but the data doesn't meet business rules.

POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "", "age": -5}

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "errors": {
    "name": "Name cannot be empty",
    "age": "Age must be positive"
  }
}

429 Too Many Requests

The user has sent too many requests in a given time period. This is used for rate limiting to prevent abuse and ensure fair resource usage.

Include Retry-After header to tell the client when they can retry.

Status Code Name Common Cause How to Fix
400 Bad Request Malformed syntax or invalid data Check request format and data types
401 Unauthorized Missing or invalid credentials Provide valid authentication
403 Forbidden Insufficient permissions Request access or use authorized account
404 Not Found Resource doesn't exist Verify URL and resource ID
429 Too Many Requests Rate limit exceeded Wait and retry with backoff

5xx Server Errors

Server error codes indicate that the server failed to fulfill a valid request. These errors mean something went wrong on the server side, and the client generally can't fix the issue by modifying the request.

500 Internal Server Error

The generic server error. Something went wrong on the server, but it doesn't fit into a more specific 5xx category. This is often caused by unhandled exceptions, configuration errors, or unexpected conditions.

When you see this error, check server logs for stack traces and error details. Never expose internal error details to clients in production – log them server-side instead.

GET /api/users HTTP/1.1

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{"error": "An unexpected error occurred"}

501 Not Implemented

The server doesn't support the functionality required to fulfill the request. This might be used for HTTP methods that aren't implemented yet or features that are planned but not available.

502 Bad Gateway

The server, while acting as a gateway or proxy, received an invalid response from the upstream server. This commonly occurs when a reverse proxy can't reach the application server, or the application server returns a malformed response.

Common causes include application server crashes, network issues between proxy and application, or application server overload.

503 Service Unavailable

The server is temporarily unable to handle the request. This is often used during maintenance, when the server is overloaded, or when a required service is down.

Include a Retry-After header to indicate when the client should try again.

GET /api/users HTTP/1.1

HTTP/1.1 503 Service Unavailable
Retry-After: 3600

{"error": "Service temporarily unavailable for maintenance"}

504 Gateway Timeout

The server, acting as a gateway or proxy, didn't receive a timely response from the upstream server. This typically means the application server is taking too long to respond.

Common causes include slow database queries, external API timeouts, or resource-intensive operations that exceed timeout limits.

Pro tip: When debugging 5xx errors, always check server logs first. These errors indicate server-side issues that require access to backend systems to diagnose and fix. Use monitoring tools like our Uptime Monitor to catch these errors before users do.

Troubleshooting Common Errors

Understanding status codes is one thing, but knowing how to fix the underlying issues is what matters. Here's a practical guide to troubleshooting the most common HTTP errors.

Debugging 404 Not Found Errors

404 errors are frustrating but usually straightforward to fix:

  1. Check the URL: Verify spelling, capitalization, and path structure
  2. Verify routing: Ensure your application's routing configuration includes the path
  3. Check file existence: For static files, confirm the file exists in the correct directory
  4. Review redirects: A misconfigured redirect might be sending requests to non-existent URLs
  5. Clear cache: Browser or CDN caching might serve stale 404 responses

For APIs, implement proper error responses that help developers understand what went wrong:

{
  "error": "Resource not found",
  "message": "User with ID 12345 does not exist",
  "code": "USER_NOT_FOUND"
}

Resolving 401 and 403 Authentication Issues

Authentication and authorization errors require different approaches:

For 401 Unauthorized:

For 403 Forbidden:

Fixing 500 Internal Server Errors

Server errors require backend investigation:

  1. Check server logs: Look for stack traces and error messages
  2. Review recent changes: Did a recent deployment introduce the bug?
  3. Test database connectivity: Many 500 errors stem from database issues
  4. Verify environment variables: Missing or incorrect configuration can cause crashes
  5. Check resource limits: Memory, disk space, or connection pool exhaustion
  6. Review third-party services: External API failures might cascade to your server

Handling 502 and 504 Gateway Errors

Gateway errors indicate communication problems between servers:

For 502 Bad Gateway:

For 504 Gateway Timeout:

Dealing with Rate Limiting (429)

When you hit rate limits, implement proper retry logic:

async function fetchWithRetry(url, options = {}, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);
    
    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After');
      const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, i) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
      continue;
    }
    
    return response;
  }
  
  throw new Error('Max retries exceeded');
}

Best practices for avoiding rate limits:

Best Practices for Developers

Using HTTP status codes correctly improves API design, debugging, and user experience. Here are essential best practices every developer should follow.

Choosing the Right Status Code

Don't default to 200 for everything. Use specific codes that accurately describe what happened: