Copied to clipboard!
Web Engineering · HTTP Protocol

HTTP Error Codes Explained
A Complete Guide

Every status code from 1xx to 5xx — what they mean, when they fire, and how to handle them. With real-world examples for developers and DevOps engineers.

AY
Anji Yarra
AWS SAA-C03 · Cloud & DevOps Engineer
May 2026
~8 min read
60 codes covered
Filter by category
HTTP status codes are the language of the web. Every time a browser or API client makes a request, the server responds with a 3-digit code that instantly communicates what happened. As a Cloud & DevOps engineer, you'll debug these daily — in ALB logs, CloudWatch alarms, Nginx access logs, and API responses. Knowing them deeply is non-negotiable.
1xx
Informational
Request received — processing continues
100
Continue
Server received request headers, client should proceed with body

Sent when the server has received the request headers and the client should proceed to send the request body. Used when sending large files — the client checks if the server is ready before uploading.

Real World Example
POST /upload HTTP/1.1
Expect: 100-continue

→ Server responds: 100 Continue
→ Client now sends the file body
Large uploadsExpect headerS3 multipart
101
Switching Protocols
Server agrees to switch to a different protocol

The server agrees to upgrade the protocol. Most commonly seen when upgrading from HTTP to WebSockets — the connection becomes a persistent, two-way channel.

WebSocket Handshake
GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade

→ HTTP/1.1 101 Switching Protocols
→ Upgrade: websocket
WebSocketsHTTP/2Real-time apps
102
Processing
Server has received and is processing (no response yet)

A WebDAV extension code indicating the server has received the request but hasn't finished processing. Prevents the client from timing out on long operations.

WebDAVLong operations
2xx
Success
Request successfully received, understood, and accepted
200
OK
The most common success response — request succeeded

The standard success response. The meaning depends on the HTTP method: GET returns the resource, POST returns the result, PUT returns the updated resource. Your ALB health checks should always aim to see 200 from your EC2 targets.

AWS Context
ALB Target Health Check → 200 OK
EC2 instance is HEALTHY ✓

GET /api/users → 200 OK
{"users": [...], "count": 42}
GETPOSTPUTALB health check
201
Created
Request succeeded and a new resource was created

Returned after a POST request successfully creates a resource. The response typically includes a Location header pointing to the new resource's URL.

REST API Example
POST /api/users
{"name": "Anji", "role": "cloud-engineer"}

→ 201 Created
Location: /api/users/123
POSTREST APIResource creation
202
Accepted
Request accepted but not yet completed — async processing

The request has been accepted for processing, but processing hasn't completed. Common with async jobs — like triggering an AWS Lambda or SQS message and returning immediately while processing happens in background.

AsyncSQSLambdaBackground jobs
204
No Content
Success — but no body to return

The server successfully processed the request but is not returning any content. Used for DELETE operations, or PUT updates where you don't need to return the full resource back to the client.

DELETE Example
DELETE /api/users/123

→ 204 No Content
(no response body)
DELETEPUTNo body
206
Partial Content
Only part of the resource is being delivered (Range requests)

Used when the client sends a Range header to request only part of a resource. Common in video streaming, S3 byte-range reads, and download resumption.

S3 Byte Range
GET /video.mp4
Range: bytes=0-1023

→ 206 Partial Content
Content-Range: bytes 0-1023/5242880
S3Video streamingRange header
3xx
Redirection
Further action needed to complete the request
301
Moved Permanently
Resource has permanently moved — update your bookmarks

The resource has permanently moved to a new URL. Browsers cache this. Search engines transfer SEO juice. In AWS, you'll configure 301 redirects on ALB listener rules — for example, forcing HTTP → HTTPS.

ALB HTTP → HTTPS Redirect
ALB Listener Rule (Port 80):
Action: Redirect to HTTPS
Status Code: 301

GET http://anjidevops.online
→ 301 → https://anjidevops.online
SEOALB redirectHTTP→HTTPSPermanent
302
Found (Temporary Redirect)
Resource temporarily at a different URL — don't cache

Temporary redirect — the original URL is still valid. Browsers don't cache this. Use 301 for permanent changes, 302 for temporary ones (maintenance pages, A/B testing).

TemporaryA/B testingMaintenance
304
Not Modified
Client's cached version is still valid — use cache

The server tells the client "your cached copy is still fresh, use it." No body is sent, saving bandwidth. CloudFront uses this extensively for cache validation. Triggered by If-Modified-Since or ETag headers.

CloudFront Cache Validation
GET /style.css
If-None-Match: "abc123"

→ 304 Not Modified
(no body — use cached copy)
CloudFrontETagCacheBandwidth saving
307
Temporary Redirect
Like 302, but method must NOT change

Temporary redirect that guarantees the HTTP method won't change. If a POST is redirected with 302, some browsers change to GET. 307 prevents this — POST stays POST.

POST safeTemporaryMethod preserved
308
Permanent Redirect
Like 301, but method must NOT change

Permanent redirect that preserves the HTTP method. The modern, stricter version of 301. If you POST to a URL and it's permanently moved, 308 ensures the client POSTs to the new URL too.

PermanentPOST safeModern
4xx
Client Errors
The request contains bad syntax or cannot be fulfilled
400
Bad Request
Server can't process — malformed syntax or invalid request

The server cannot process the request due to invalid syntax. Often caused by malformed JSON, missing required fields, or invalid query parameters. The client must fix the request before retrying.

Invalid JSON Body
POST /api/deploy
{"region": "ap-south-1", "count": } ← broken JSON

→ 400 Bad Request
{"error": "Invalid JSON syntax at line 1"}
ValidationMalformed JSONMissing fields
401
Unauthorized
Authentication required — who are you?

Despite the name, this is about authentication, not authorization. The client must authenticate to get the requested response. Common with expired JWT tokens, missing API keys, or invalid AWS credentials.

Expired Token
GET /api/instances
Authorization: Bearer eyJ... (expired)

→ 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
JWT expiredAPI key missingIAM credentials
403
Forbidden
Authenticated but not authorized — we know who you are, but you can't do this

The client is authenticated but lacks permission. In AWS, this is extremely common — IAM policy denies, S3 bucket policies, Security Group blocks. The key difference from 401: re-authenticating won't help.

AWS S3 Access Denied
GET s3://prod-bucket/config.env
IAM user: dev-user

→ 403 AccessDenied
Bucket policy blocks this IAM principal
IAM policyS3 bucket policyLeast privilege
404
Not Found
The most famous one — resource doesn't exist at this URL

The server can't find the requested resource. The URL is valid, but there's nothing there. Also used to hide existence of resources for security. If your ALB target returns 404, check your Nginx config and file paths.

Nginx Root Misconfigured
GET /index.html
Nginx root: /var/www/html/
File: /usr/share/nginx/html/index.html

→ 404 Not Found (wrong root path)
Nginx rootMissing fileWrong URL
405
Method Not Allowed
HTTP method not supported for this endpoint

The endpoint exists, but doesn't support the HTTP method used. E.g. sending a DELETE to a read-only endpoint, or POST to a GET-only route. The response includes an Allow header listing valid methods.

Example
DELETE /api/config
→ 405 Method Not Allowed
Allow: GET, POST
REST APIWrong method
408
Request Timeout
Server timed out waiting for the request

The client took too long to send the request. ALB has an idle timeout (default 60s). If a client opens a connection but doesn't send a request within that window, the connection is closed.

ALB timeoutIdle connectionSlow client
409
Conflict
Request conflicts with current state of the resource

The request conflicts with the current state. Classic examples: trying to create a user that already exists, editing a resource that was modified by someone else (version mismatch), or duplicate record violations.

Duplicate Resource
POST /api/users
{"email": "anji@example.com"}

→ 409 Conflict
{"error": "User with this email already exists"}
DuplicateVersion conflictRace condition
410
Gone
Resource existed but was permanently deleted — stronger than 404

The resource existed but has been permanently removed. Unlike 404, 410 tells clients and search engines definitively: this is gone forever, stop requesting it and remove it from your index.

SEODeleted resourceDeprecated API
422
Unprocessable Entity
Syntax OK but semantically wrong — validation failure

The request was well-formed but failed semantic validation. JSON is valid, but the data doesn't make sense. Common in REST APIs and form submissions — age: -5, or an email field with "notanemail".

Validation Error
POST /api/ec2/launch
{"instance_type": "invalid_type", "count": -1}

→ 422 Unprocessable Entity
{"errors": ["Invalid instance_type", "count must be > 0"]}
ValidationSemantic errorForm data
429
Too Many Requests
Rate limit exceeded — slow down

The client has sent too many requests in a given time. Critical for API rate limiting and DDoS mitigation. AWS API Gateway returns 429 when throttling. Response includes Retry-After header with seconds to wait.

AWS API Gateway Throttle
GET /api/data (called 1000x/sec)
Limit: 100 req/sec

→ 429 Too Many Requests
Retry-After: 10
X-RateLimit-Remaining: 0
Rate limitingAPI GatewayWAFDDoS
5xx
Server Errors
Server failed to fulfil a valid request — it's not the client's fault
500
Internal Server Error
The server hit an unexpected condition — generic catch-all

The server encountered an unexpected condition. The generic server-side error. Could be: unhandled exception in your app code, database query failure, memory overflow, or misconfigured application. Check your CloudWatch logs immediately.

CloudWatch Alert
ALB Metric: HTTPCode_Target_5XX_Count > 0
→ CloudWatch Alarm: ALARM state
→ Check Nginx error.log on EC2:
[ERROR] Unhandled exception: DB connection refused
App crashCloudWatch logsDB failureException
501
Not Implemented
Server doesn't support the functionality required

The server doesn't know how to handle the request method. Unlike 405 (method not allowed for this route), 501 means the server doesn't implement this HTTP method at all. Rare in practice.

Unimplemented methodProtocol support
502
Bad Gateway
Proxy/gateway got invalid response from upstream server

The gateway (e.g. Nginx, ALB) received an invalid response from the upstream backend. In AWS: ALB forwards request to EC2 → EC2 returns garbage or crashes mid-response → ALB shows 502 to client. Also seen when EC2 is misconfigured or Nginx upstream is wrong.

ALB → EC2 502
User → ALB → EC2 (Nginx)

EC2 Nginx crash or wrong upstream port
→ ALB returns 502 Bad Gateway

Fix: Check target group health in ALB console
Check: sudo journalctl -u nginx -n 50
ALB targetNginx upstreamEC2 crashProxy error
503
Service Unavailable
Server is down — overloaded or under maintenance

The server is temporarily unable to handle the request. In AWS: all ALB targets fail health checks → ALB returns 503 to all incoming requests. This is your biggest production alert. Add a Retry-After header during planned maintenance.

ALB No Healthy Targets
ALB Target Group Health Check:
Target 10.0.1.5:80 → UNHEALTHY
Target 10.0.2.5:80 → UNHEALTHY

→ All requests return 503
→ CloudWatch: HealthyHostCount = 0 → ALARM
ALB health checkOverloadedMaintenanceScale out
504
Gateway Timeout
Upstream server didn't respond in time

The gateway didn't receive a timely response from the upstream server. In AWS: ALB idle timeout is 60s by default. If EC2 takes longer than 60s to respond, ALB returns 504. Fix: increase ALB idle timeout, or optimize slow queries.

ALB Timeout Fix
EC2 response time: 90s (slow DB query)
ALB idle timeout: 60s (default)
→ 504 Gateway Timeout

Fix Option 1: ALB console → Attributes
→ Idle timeout: 120 seconds
Fix Option 2: Optimize the slow query
ALB timeoutSlow queryRDS performanceLambda timeout
505
HTTP Version Not Supported
Server doesn't support the HTTP version used

The server doesn't support the HTTP protocol version used. Rare in modern infrastructure. Can appear when a client tries HTTP/3 against a server only supporting HTTP/1.1.

HTTP versionProtocol mismatch