HTTP Status Codes: Complete Reference Guide

HTTP Status Codes: Complete Reference Guide

Every HTTP request returns a status code that tells you exactly what happened. Understanding HTTP status codes is essential for web developers, API engineers, and anyone working with web scraping or proxy infrastructure. This complete reference guide covers every status code category with practical examples and troubleshooting tips.

What Are HTTP Status Codes?

HTTP status codes are three-digit numbers returned by a server in response to a client’s request. They are grouped into five classes based on the first digit, each indicating a different type of response.

1xx Informational Responses

These codes indicate the server has received the request and is continuing to process it.

CodeNameDescription
100ContinueThe server received the request headers; the client should send the body
101Switching ProtocolsThe server is switching to the protocol requested (e.g., WebSocket)
102ProcessingThe server is processing a long request (WebDAV)
103Early HintsUsed with the Link header to preload resources

2xx Success

Success codes confirm the request was received, understood, and accepted.

CodeNameDescription
200OKStandard success response
201CreatedA new resource was successfully created
202AcceptedRequest accepted for processing but not yet completed
204No ContentSuccess with no response body
206Partial ContentPartial resource returned (used with Range headers)

Checking Status Codes with cURL

# View the response status code

curl -o /dev/null -s -w "%{http_code}" https://example.com

View full response headers including status line

curl -I https://example.com

import requests

response = requests.get("https://example.com")

print(f"Status Code: {response.status_code}")

print(f"Reason: {response.reason}")

3xx Redirection

These codes indicate the client must take additional action to complete the request, usually following a redirect.

CodeNameDescription
301Moved PermanentlyResource has been permanently moved to a new URL
302FoundTemporary redirect to another URL
303See OtherRedirect using GET method (often after POST)
304Not ModifiedCached version is still valid
307Temporary RedirectLike 302 but preserves the HTTP method
308Permanent RedirectLike 301 but preserves the HTTP method

Handling Redirects

# Follow redirects automatically

curl -L https://example.com/old-page

Show redirect chain

curl -L -v https://example.com/old-page 2>&1 | grep "< HTTP\|< location"

Limit redirect depth

curl -L --max-redirs 5 https://example.com

import requests

Follow redirects (default behavior)

response = requests.get("https://example.com/old-page")

print(f"Final URL: {response.url}")

print(f"Redirect history: {[r.status_code for r in response.history]}")

Disable auto-redirect

response = requests.get("https://example.com/old-page", allow_redirects=False)

print(f"Status: {response.status_code}")

print(f"Location: {response.headers.get('Location')}")

4xx Client Errors

Client error codes indicate the request contains an error or cannot be fulfilled.

CodeNameDescription
400Bad RequestMalformed syntax or invalid request
401UnauthorizedAuthentication required
403ForbiddenServer refuses to authorize the request
404Not FoundResource does not exist
405Method Not AllowedHTTP method not supported for this endpoint
407Proxy Authentication RequiredProxy credentials needed
408Request TimeoutServer timed out waiting for the request
409ConflictRequest conflicts with current server state
410GoneResource permanently removed
413Payload Too LargeRequest body exceeds server limits
415Unsupported Media TypeContent-Type not supported
422Unprocessable EntityValid syntax but semantic errors
429Too Many RequestsRate limit exceeded
451Unavailable For Legal ReasonsBlocked for legal reasons

Common 4xx Fixes

# Debug 400 errors - check your request format

curl -v -X POST https://api.example.com/data \

-H "Content-Type: application/json" \

-d '{"key": "value"}'

Fix 401 - add authentication

curl -u username:password https://api.example.com/protected

curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/protected

Fix 407 - add proxy authentication

curl -x http://proxy:8080 --proxy-user user:pass https://example.com

5xx Server Errors

Server error codes indicate the server failed to fulfill a valid request.

CodeNameDescription
500Internal Server ErrorGeneric server-side error
501Not ImplementedServer does not support the request method
502Bad GatewayInvalid response from upstream server
503Service UnavailableServer temporarily overloaded or under maintenance
504Gateway TimeoutUpstream server did not respond in time
507Insufficient StorageServer cannot store the request (WebDAV)
508Loop DetectedInfinite redirect loop detected (WebDAV)
511Network Authentication RequiredNetwork login required (captive portal)

Cloudflare-Specific Status Codes

Cloudflare uses custom 5xx codes for issues between Cloudflare and the origin server:

CodeNameDescription
520Web Server Returned an Unknown ErrorOrigin returned unexpected response
521Web Server Is DownOrigin server refused the connection
522Connection Timed OutTCP handshake with origin timed out
523Origin Is UnreachableDNS records point to unreachable IP
524A Timeout OccurredTCP connection made but HTTP response timed out
525SSL Handshake FailedSSL/TLS handshake with origin failed
526Invalid SSL CertificateOrigin SSL certificate is invalid
527Railgun ErrorCloudflare Railgun connection error
530Origin DNS ErrorDNS lookup for origin failed (often with 1xxx error)

Status Code Decision Flowchart

When you encounter an error, follow this diagnostic approach:

  1. Is it 4xx? → The problem is with your request. Check URL, headers, body, and authentication.
  2. Is it 5xx? → The problem is on the server. Retry with exponential backoff.
  3. Is it 3xx? → Follow the redirect or update your saved URL.
  4. Is it 429? → You are being rate-limited. Slow down and add delays between requests.

Retry Logic for Server Errors

import requests

import time

def request_with_retry(url, max_retries=3, backoff_factor=2):

for attempt in range(max_retries):

response = requests.get(url)

if response.status_code == 200:

return response

if response.status_code in [429, 500, 502, 503, 504]:

wait_time = backoff_factor ** attempt

if response.status_code == 429:

# Check Retry-After header

retry_after = response.headers.get("Retry-After")

if retry_after:

wait_time = int(retry_after)

print(f"Got {response.status_code}, retrying in {wait_time}s...")

time.sleep(wait_time)

else:

response.raise_for_status()

raise Exception(f"Failed after {max_retries} retries")

Using Proxies to Handle Status Codes

Many 4xx errors (especially 403 and 429) occur because the server is blocking your IP. Using residential proxies can help bypass these blocks by rotating your IP address.

# Rotate through proxies to avoid rate limiting

curl -x http://user:pass@proxy.example.com:8080 https://target-site.com


FAQ

What is the most common HTTP status code?

200 OK is the most common status code, indicating a successful request. Among errors, 404 Not Found is the most frequently encountered.

What is the difference between 401 and 403?

A 401 Unauthorized means authentication is required but was not provided or is invalid. A 403 Forbidden means the server understood the request but refuses to authorize it, even with valid credentials.

How do I check HTTP status codes in a browser?

Open DevTools (F12), go to the Network tab, and reload the page. Each request shows its status code in the Status column.

What should I do when I get a 5xx error?

Server errors are usually temporary. Wait and retry with exponential backoff. If the error persists, contact the website administrator or check their status page.

Are HTTP status codes case-sensitive?

No. Status codes are numeric (three digits) and are not case-sensitive. The reason phrases (like “OK” or “Not Found”) are optional and can vary by implementation.

Scroll to Top