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.
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.