Quick answer
HTTP 503 Service Unavailable means the server is temporarily unable to handle the request, usually because it is overloaded or down for maintenance. It often includes a Retry-After header.
What HTTP 503 means
503 Service Unavailable is a temporary server-side condition. The server is reachable but deliberately not serving the request right now — it may be overloaded, scaling, or in maintenance. Because it is temporary, the response often includes a Retry-After header, and clients should retry later.
Common causes
- The server is overloaded and shedding traffic
- Planned maintenance or a deployment in progress
- Health checks failing, so a load balancer pulls the instance
- Autoscaling has not yet added enough capacity
Example JSON error response
{
"error": "Service Unavailable",
"message": "The service is temporarily unavailable. Please retry shortly.",
"status": 503,
"retry_after": 120
}
Raw HTTP response
HTTP/1.1 503 Service Unavailable
Retry-After: 120
Content-Type: application/json
How to troubleshoot HTTP 503
- ✓ Check server load and resource usage (CPU, memory)
- ✓ Confirm whether the service is in maintenance mode
- ✓ Honor the
Retry-Afterheader before retrying - ✓ Check health checks and load balancer status
- ✓ Scale capacity if the cause is sustained overload
502 vs 503 vs 504 — what's the difference?
502 Bad Gateway: the proxy got an invalid response from the upstream. 503 Service Unavailable: the server is up but temporarily can't serve the request (overload/maintenance). 504 Gateway Timeout: the upstream didn't respond in time. 503 is the one that is usually temporary and self-resolving.
Handling a 503 in client code
503 is the most "retry-friendly" 5xx — it explicitly signals a temporary condition and usually tells you when to come back via Retry-After. Honor that header; only fall back to backoff if it's absent:
const res = await fetch('/api/data');
if (res.status === 503) {
const after = res.headers.get('Retry-After'); // seconds or HTTP date
const waitMs = after ? Number(after) * 1000 : 5000;
await new Promise(r => setTimeout(r, waitMs));
return fetch('/api/data'); // retry once after waiting
}
Returning a proper 503 (if you run the server)
During maintenance or overload, return 503 with a Retry-After header rather than letting requests hang or fail with a 500. Two benefits: clients (and search-engine crawlers) know it's temporary and won't treat the outage as permanent, and well-behaved clients space out their retries instead of hammering a struggling server.
- Maintenance: serve 503 +
Retry-Afterfrom the load balancer so the app can be taken fully offline. - Overload: shed excess traffic with 503 at the edge to protect the core from collapsing entirely.
- SEO note: a 503 during maintenance tells Google to come back later — unlike a 500 or a broken 200 page, it won't hurt rankings.
Frequently Asked Questions
What does 503 Service Unavailable mean?
The server is temporarily unable to handle the request — typically because it is overloaded or down for maintenance. It is a temporary condition, and the response often includes a Retry-After header telling clients when to try again.
How do I fix a 503 error?
If you run the server: check load and resource usage, confirm whether maintenance mode is on, review health checks, and scale capacity if it is sustained overload. If you are the client: honor Retry-After and retry with backoff.
Is a 503 error permanent?
No. 503 signals a temporary condition by design. It usually resolves once load drops, maintenance ends, or capacity scales up. That is why clients are expected to retry after the Retry-After interval.
Is a 503 bad for SEO?
Not if it's used correctly. A 503 with a Retry-After header tells search engines the outage is temporary and to come back later, so it protects rankings during planned maintenance. What hurts SEO is serving a 500, or a broken 200 page, instead — those can be treated as permanent problems.
Should I use 500 or 503 during maintenance?
Use 503. A 500 implies an unexpected bug, while 503 explicitly means "temporarily unavailable, try again." Pair it with a Retry-After header so clients and crawlers know when to return. Serving 503 from the load balancer also lets you take the app fully offline during the deploy.
Working with a JSON API response?
Format and inspect any response in your browser — nothing is uploaded.