Guide

Complete Guide to HTTP Status Codes

Master HTTP status codes with our comprehensive guide. Learn about all 1xx, 2xx, 3xx, 4xx, and 5xx codes with practical examples and best practices for web developers.

Pavel Volkov
Aug 30, 2025
4 min read

Introduction to HTTP Status Codes

HTTP status codes are three-digit numbers that web servers send to browsers to indicate the result of a client's request. Understanding these codes is crucial for web developers, system administrators, and anyone working with web applications.

Understanding the Structure

HTTP status codes are organized into five classes based on the first digit:

  • 1xx (Informational): The request was received, continuing process
  • 2xx (Successful): The request was successfully received, understood, and accepted
  • 3xx (Redirection): Further action needs to be taken to complete the request
  • 4xx (Client Error): The request contains bad syntax or cannot be fulfilled
  • 5xx (Server Error): The server failed to fulfill an apparently valid request

1xx Informational Responses

100 Continue

The server has received the request headers and the client should proceed to send the request body.

// Example: Large file upload with Expect header
curl -X POST -H "Expect: 100-continue" -d @largefile.json https://api.example.com/upload

101 Switching Protocols

The server is switching protocols according to the Upgrade header field.

2xx Successful Responses

200 OK

The request has succeeded. The meaning depends on the HTTP method used.

// PHP example
if ($user->save()) {
    http_response_code(200);
    echo json_encode(['status' => 'success', 'user' => $user]);
}

201 Created

The request has been fulfilled and resulted in a new resource being created.

// JavaScript/Node.js example
app.post('/users', (req, res) => {
    const user = new User(req.body);
    user.save()
        .then(() => res.status(201).json(user))
        .catch(err => res.status(400).json({error: err.message}));
});

204 No Content

The server successfully processed the request but is not returning any content.

3xx Redirection

301 Moved Permanently

The resource has been permanently moved to a new URL.

# Apache .htaccess example
Redirect 301 /old-page.html /new-page.html

302 Found (Temporary Redirect)

The resource is temporarily located at a different URL.

304 Not Modified

The resource has not been modified since the version specified by the request headers.

4xx Client Errors

400 Bad Request

The server cannot process the request due to client error (malformed syntax, invalid request message framing, etc.).

// Python Flask example
@app.route('/api/users', methods=['POST'])
def create_user():
    if not request.json or 'email' not in request.json:
        return jsonify({'error': 'Email is required'}), 400

401 Unauthorized

Authentication is required and has failed or has not been provided.

// Express.js middleware example
function requireAuth(req, res, next) {
    const token = req.headers.authorization;
    if (!token) {
        return res.status(401).json({error: 'Authorization required'});
    }
    // Verify token logic here
    next();
}

403 Forbidden

The client does not have access rights to the content.

404 Not Found

The server can not find the requested resource.

// Laravel example
Route::fallback(function () {
    return response()->json(['error' => 'Route not found'], 404);
});

5xx Server Errors

500 Internal Server Error

A generic error message when the server encounters an unexpected condition.

// Error handling example
try {
    // Some operation that might fail
    $result = processComplexOperation();
} catch (Exception $e) {
    error_log("Server error: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['error' => 'Internal server error']);
}

502 Bad Gateway

The server, while acting as a gateway or proxy, received an invalid response from an upstream server.

503 Service Unavailable

The server is currently unavailable (overloaded or down for maintenance).

Best Practices for Developers

API Response Consistency

Always use appropriate status codes with consistent response formats:

// Good practice - consistent error format
{
    "error": {
        "code": 400,
        "message": "Validation failed",
        "details": {
            "email": ["Email is required"],
            "password": ["Password must be at least 8 characters"]
        }
    }
}

Frontend Error Handling

// JavaScript fetch with proper error handling
async function apiCall(url, options) {
    try {
        const response = await fetch(url, options);
        
        if (!response.ok) {
            if (response.status === 401) {
                // Redirect to login
                window.location.href = '/login';
                return;
            }
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        return await response.json();
    } catch (error) {
        console.error('API call failed:', error);
        throw error;
    }
}

Testing HTTP Status Codes

Use tools like curl, Postman, or write automated tests to verify your API returns correct status codes:

# Testing with curl
curl -I -X GET https://api.example.com/users/123

# Expected response headers
HTTP/2 200 
content-type: application/json
cache-control: max-age=300

Common Mistakes to Avoid

  • Returning 200 OK for errors in the response body
  • Using 404 for unauthorized access (use 401 or 403 instead)
  • Not implementing proper caching with 304 Not Modified
  • Ignoring 5xx errors in production monitoring

Monitoring and Logging

Set up proper monitoring to track status code patterns:

// Example monitoring setup
if (response.status >= 500) {
    logger.error("Server error", {
        url: request.url,
        method: request.method,
        status: response.status,
        user_id: user?.id
    });
}

Understanding and properly implementing HTTP status codes is essential for building robust, maintainable web applications. They provide valuable information for debugging, monitoring, and creating better user experiences.

Last updated: Sep 05, 2025