API/HTTP Error Fixes -- How to Fix Common API Errors
API errors like 400 Bad Request and 500 Internal Server Error break client-server communication -- this guide shows you how to diagnose and fix the most common HTTP status code errors with request/response analysis and server-side fixes.
What You'll Learn
Why It Matters
REST API errors affect every developer who builds or consumes web services. Understanding HTTP status codes and their fixes helps you debug integrations faster and build more reliable APIs.
Real-World Use
When your frontend app receives a 403 Forbidden or a third-party API returns 429 Too Many Requests, knowing how to interpret the status code and apply the correct fix keeps your application functional.
Common API Errors Table
| Error Message / Status | Cause | Fix |
|---|---|---|
| 400 Bad Request | Malformed request body, missing required fields | Validate request payload against API schema |
| 401 Unauthorized | Missing or invalid authentication token | Include valid Authorization: Bearer <token> header |
| 403 Forbidden | Authenticated but lacking permission | Check user roles and permissions for the resource |
| 404 Not Found | Resource endpoint or ID does not exist | Verify the URL path and resource ID |
| 405 Method Not Allowed | HTTP method not supported for the endpoint | Use the correct HTTP method (GET, POST, PUT, DELETE) |
| 429 Too Many Requests | Rate limit exceeded | Implement exponential backoff retry logic |
| 500 Internal Server Error | Server-side exception or unhandled error | Check server logs, add error handling middleware |
Step-by-Step Fixes
Fix 1: 400 Bad Request
# bad -- missing required field in request body
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice"}'
# {"error": "Bad Request", "message": "email is required"}
# fixed -- include all required fields
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}'
Expected output:
{"id": 123, "name": "Alice", "email": "alice@example.com"}
Fix 2: 401 Unauthorized
# bad -- no auth token provided
curl https://api.example.com/profile
# {"error": "Unauthorized", "message": "Missing authentication token"}
# fixed -- include Bearer token
TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/profile
Expected output:
{"id": 123, "name": "Alice", "email": "alice@example.com"}
Fix 3: 404 Not Found
# bad.py -- wrong endpoint or ID
import requests
response = requests.get("https://api.example.com/users/99999")
print(response.status_code) # 404
print(response.json()) # {"error": "User not found"}
# fixed.py -- verify the resource exists first
import requests
user_id = 99999
# Check if user exists
response = requests.get(f"https://api.example.com/users/{user_id}")
if response.status_code == 404:
print(f"User {user_id} does not exist")
elif response.status_code == 200:
print(response.json())
Expected output:
User 99999 does not exist
Fix 4: 405 Method Not Allowed
# bad -- using wrong HTTP method
curl -X PUT https://api.example.com/users/123
# {"error": "Method Not Allowed", "message": "Supported methods: GET, DELETE"}
# fixed -- use a supported method
curl -X GET https://api.example.com/users/123
Expected output:
{"id": 123, "name": "Alice", "email": "alice@example.com"}
Fix 5: 429 Too Many Requests
# bad -- hitting rate limit
for i in {1..100}; do
curl -s https://api.example.com/data
done
# {"error": "Too Many Requests", "retry_after": 60}
# fixed.py -- implement exponential backoff
import requests
import time
def fetch_with_retry(url, max_retries=5):
for attempt in range(max_retries):
response = requests.get(url)
if response.status_code == 429:
wait = int(response.headers.get("Retry-After", 2 ** attempt))
print(f"Rate limited, waiting {wait}s...")
time.sleep(wait)
continue
return response
return response
result = fetch_with_retry("https://api.example.com/data")
print(result.status_code)
Expected output:
Rate limited, waiting 1s...
Rate limited, waiting 2s...
200
Fix 6: 500 Internal Server Error
// bad -- server has unhandled exception
fetch("https://api.example.com/users/123")
.then(res => res.json())
.then(data => console.log(data))
// {"error": "Internal Server Error"}
// fixed -- add proper error handling and logging on server side
// Express.js example
app.get("/api/users/:id", async (req, res) => {
try {
const user = await db.findUser(req.params.id);
if (!user) {
return res.status(404).json({ error: "User not found" });
}
res.json(user);
} catch (err) {
console.error("Error fetching user:", err);
res.status(500).json({ error: "Internal Server Error" });
}
});
Expected output:
{"id": 123, "name": "Alice", "email": "alice@example.com"}
API Error Diagnosis Flowchart
flowchart TD
A[API Error Detected] --> B{HTTP Status Code?}
B -->|4xx Client Error| C{Which Code?}
C -->|400| D[Check request body and params]
C -->|401| E[Check auth token]
C -->|403| F[Check user permissions]
C -->|404| G[Verify resource URL and ID]
C -->|405| H[Use correct HTTP method]
C -->|429| I[Implement retry with backoff]
B -->|5xx Server Error| J{Which Code?}
J -->|500| K[Check server logs for exceptions]
J -->|502| L[Check upstream services]
J -->|503| M[Service overloaded -- scale up]
D --> N[Error Resolved]
E --> N
F --> N
G --> N
H --> N
I --> N
K --> N
L --> N
M --> N
Prevention Tips
- Use OpenAPI/Swagger specifications to document all request bodies and parameters
- Implement centralized error handling middleware in your API framework
- Always validate request payloads with a schema validator (Joi, Pydantic, Zod)
- Use proper HTTP methods: GET for reads, POST for creates, PUT for updates, DELETE for deletions
- Implement rate limiting with meaningful
Retry-Afterheaders on the server - Log all 5xx errors with full stack traces for debugging
- Add health check endpoints for monitoring and load balancer configuration
Practice Questions
What is the difference between 401 Unauthorized and 403 Forbidden? Answer: 401 means the client is not authenticated (no valid token). 403 means the client is authenticated but does not have permission to access the resource.
How do you handle a 429 Too Many Requests error in client code? Answer: Implement exponential backoff: wait 1s, 2s, 4s, 8s between retries, reading the
Retry-Afterheader if present.What causes a 405 Method Not Allowed error? Answer: The client used an HTTP method that the server does not support for that endpoint. Check the API documentation for supported methods.
How do you debug a 500 Internal Server Error? Answer: Check the server application logs for unhandled exceptions, add try-catch blocks around risky operations, and use logging middleware.
Challenge: Write a Python function that makes an API request with automatic handling of 401 (refresh token), 429 (exponential backoff), and 5xx (retry up to 3 times) status codes, with a configurable maximum retry count. Answer:
import requests import time from functools import wraps def resilient_api_call(max_retries=3, base_delay=1): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_retries): response = func(*args, **kwargs) if response.status_code == 200: return response elif response.status_code == 401: print("Refreshing token...") new_token = refresh_auth_token() kwargs["headers"] = kwargs.get("headers", {}) kwargs["headers"]["Authorization"] = f"Bearer {new_token}" elif response.status_code == 429: wait = int(response.headers.get("Retry-After", base_delay * (2 ** attempt))) print(f"Rate limited, waiting {wait}s...") time.sleep(wait) elif response.status_code >= 500: if attempt == max_retries - 1: raise Exception(f"API failed after {max_retries} retries") time.sleep(base_delay * (2 ** attempt)) else: return response return response return wrapper return decorator def refresh_auth_token(): return "new_token_here" @resilient_api_call(max_retries=3) def call_api(url, headers=None): return requests.get(url, headers=headers) result = call_api("https://api.example.com/data") print(result.status_code)
Quick Reference
| Status | Meaning | Quick Fix |
|---|---|---|
| 400 | Bad Request | Validate request body format and required fields |
| 401 | Unauthorized | Add valid Bearer token to Authorization header |
| 403 | Forbidden | Check user role and resource permissions |
| 404 | Not Found | Verify URL path and resource ID correctness |
| 405 | Method Not Allowed | Use the correct HTTP method for the endpoint |
| 429 | Too Many Requests | Implement exponential backoff retry logic |
| 500 | Internal Server Error | Check server logs and add error handling |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro