503 Service Unavailable: what it means and how to fix it

503 Service Unavailable means the server can't handle the request right now because it's overloaded, down for maintenance, or has no healthy backend to route to. Unlike a 500, it signals a temporary condition. The server may include a Retry-After header with its estimate of when to try again.

HTTP/1.1 503 Service Unavailable
Retry-After: 120
Content-Type: application/json

{"error": "maintenance", "message": "Scheduled maintenance, back in about 2 minutes"}

Common causes

  • Planned maintenance. The app or a load balancer returns a maintenance page with 503.
  • Overload. Every worker or thread is busy, connection pools are exhausted, or an autoscaler hasn't caught up yet.
  • No healthy backends. An AWS ALB target group with no healthy targets, a Kubernetes Service with no ready pods, or a deploy that took every instance down at once.
  • Rate or connection limits. nginx limit_req and limit_conn reject excess requests with 503 by default.
  • A dependency outage. The app deliberately answers 503 when its database or a required service is down.

How to fix it as a visitor

Wait and retry. Most 503s clear within minutes. Check the service's status page or social accounts for maintenance notices. Repeated refreshing during an overload makes it worse for everyone.

How to fix it as a developer or ops

WhereLikely causeFix
nginxlimiting requests in the error logRaise the limit_req rate or burst, or set limit_req_status 429; so clients see the correct code.
ingress-nginx / KubernetesService has no ready endpointskubectl get endpoints <svc>; fix failing readiness probes or the selector.
AWS ALBNo registered or healthy targetsCheck target health and the health-check path; make sure deploys keep some targets in service.
CloudflareOrigin or Worker overloadedCheck origin capacity; a 503 from Cloudflare itself can also mean a Worker exceeded its limits.
App serversWorkers saturatedAdd workers or instances, fix slow queries, add caching.

Two general practices prevent most 503s during deploys: rolling deploys that keep some instances serving, and readiness checks that only route traffic to instances that have finished starting.

Handling a 503 as an API client

  1. Honour Retry-After. It's either a number of seconds (Retry-After: 120) or an HTTP date. Don't retry before then.
  2. Otherwise back off exponentially with jitter: 1s, 2s, 4s, 8s plus a random offset, with a cap on attempts. See exponential backoff.
  3. Only retry safe requests automatically. GET, PUT and DELETE are idempotent. Retry a POST only if the API supports idempotency keys, or you may create the same thing twice.
  4. Use a circuit breaker for dependencies that return 503 repeatedly, so your own service fails fast instead of piling up waiting requests.

503s on a webhook endpoint

Deploys are the most common source of webhook 503s. For a minute or two, every delivery fails. Providers retry, but their retry windows are short and each one is different, and a longer outage can run past the window entirely.

Webhook Relay durable retries take that timing out of the provider's hands. Every event is stored before delivery and retried with exponential backoff for up to 30 days, so webhooks sent during a deploy or outage wait until your endpoint returns 2xx. If the 503s come from overload rather than downtime, outbound throttling releases events at a fixed rate or concurrency so a burst never saturates your workers in the first place.

When to return 503 from your own API

Return 503 when the whole service, or a whole endpoint, is temporarily unable to serve anyone: maintenance, overload, a required dependency down. Include Retry-After (seconds or an HTTP date) so well-behaved clients wait instead of hammering you. If only one client is over its quota, use 429 Too Many Requests. If your code simply crashed, that's a 500.

Frequently asked questions

What does 503 Service Unavailable mean?

HTTP 503 means the server can't handle the request right now because it is overloaded, down for maintenance, or has no healthy backend to send it to. The condition is meant to be temporary. The server may include a Retry-After header saying when to try again.

How long does a 503 error last?

It depends on the cause. A deploy or restart usually clears in seconds to minutes, an overload clears when traffic drops or capacity is added, and planned maintenance lasts as long as the window. If the response has a Retry-After header, that's the server's own estimate.

What is the difference between 503 and 429?

429 Too Many Requests means you, a specific client, are over your rate limit while the service works fine for others. 503 Service Unavailable means the service as a whole can't take requests right now, for everyone.

Why does nginx return 503?

Two common reasons. First, the limit_req or limit_conn modules reject excess requests with 503 by default, unless you set limit_req_status to 429. Second, the configuration returns 503 on purpose, typically a maintenance page set up with return 503 or an error_page rule. Check the error log for limiting requests, and grep the config for 503.

Do webhook providers retry a 503?

Most providers retry 5xx responses, and some honour the Retry-After header on a 503. But each provider has its own retry window, often hours or a few days, sometimes minutes. A long outage can outlast it.