HTTP 5xx server error status codes
The 5xx class is the server admitting fault: the request may have been perfectly valid, but something on the server side — the app, a gateway, an upstream dependency, or capacity — failed. Because the client did nothing wrong, many 5xx errors are transient and worth retrying. Knowing which ones to retry, how to back off, and when to page someone is the difference between a brief blip and a cascading outage. Search the reference above by code or keyword for retry and alerting guidance on each.
The codes and what they point at
| Code | Name | Points at | Retryable |
|---|---|---|---|
500 | Internal Server Error | Your application code — unhandled exception | Cautiously |
501 | Not Implemented | Missing handler for this method | No |
502 | Bad Gateway | Upstream returned an invalid/unexpected response | Yes |
503 | Service Unavailable | Overload or planned maintenance | Yes (honour Retry-After) |
504 | Gateway Timeout | Upstream took too long to respond | Yes |
505 | HTTP Version Not Supported | Client sent an unsupported HTTP version | No |
How to read a 5xx spike
Two mental models help you triage quickly:
- Who generated it? A
500comes from your own application code; a502/504comes from a proxy or load balancer that cannot reach an upstream. Separate them in your dashboards. - When did it start? A spike that starts immediately after a deploy points at a regression in your code. A spike with no recent deploy usually points at an upstream or infrastructure issue.
How it works — the gateway family
502 Bad Gateway and 504 Gateway Timeout are mirror images. Both appear when a proxy (Nginx, a CDN, a load balancer) is healthy but cannot get a usable response from the upstream service. 502 means the upstream responded with something invalid or unexpected; 504 means it did not respond at all within the timeout. Both mean “look upstream, not at the proxy itself.”
503 Service Unavailable is the one code you should emit deliberately: during planned maintenance, or when your service is overloaded and shedding load. Always add a Retry-After header:
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: text/plain
Scheduled maintenance. Back at 14:00 UTC.
Search crawlers and well-behaved clients will respect Retry-After and avoid hammering the endpoint.
Retry strategy
For 502, 503 and 504, retry with exponential backoff and jitter:
- Wait 1s, then 2s, then 4s, then 8s (with random jitter to spread retry storms).
- Cap retries — typically 3–5 attempts.
- Only retry idempotent operations. A
GETor aDELETEcan be retried safely; aPOSTthat creates a resource should use an idempotency key.
For 500, inspect the error body and logs first — retrying a bug in your code will just generate more errors.
Alerting and observability
- Alert on the error rate (5xx as a fraction of total requests), not the absolute count. A large site may always have a handful of 500s; what matters is whether the rate has increased.
- Use separate alert rules for
500(deploy regression) and502/504(upstream health). - Track your error budget against your SLO target. A sustained 5xx rate above your allowed budget should escalate automatically.
- Never expose stack traces or internal hostnames in 5xx response bodies sent to untrusted clients — they reveal attack surface. Log internally, return a generic error externally.