503 No server available critical
HAProxy 503 Service Unavailable: No server is available to handle this request
Every backend server in the matched pool is marked DOWN, so HAProxy has nowhere to route the request and returns its own 503.
What you see
503 Service Unavailable No server is available to handle this request.
What’s actually happening
The response body is HAProxy's built-in error page, not your application's. The 503 is instant — no upstream timeout — because HAProxy already knows the pool is empty and never attempts a connection. Hit the stats page or `show stat` on the admin socket and you'll see the backend servers in a red DOWN state. If only some routes 503, you've got a host/path ACL sending traffic to a backend with no live members.
Common causes
- The backend process actually crashed or isn't listening on the configured port, so health checks fail and HAProxy marks every server DOWN
- Health check misconfiguration: `option httpchk` points at a path that returns non-2xx (a redirect, a 401, or a 404), or the check hits the wrong port, marking healthy servers DOWN
- Frontend `use_backend`/`default_backend` routing — a host or path ACL matches no backend, or matches one with zero `server` lines
- `maxconn` saturation plus full queues: all servers are at capacity and the backend queue overflows, surfacing as 503
- DNS or `server-template` resolution failure when backends are addressed by hostname and resolution breaks at reload
How to fix it
- Confirm whether the backend is actually upFrom the HAProxy host itself, curl the backend's real address and port — `curl -v http://10.0.0.5:8080/`. If that fails too, the problem is the app, not HAProxy. If it succeeds, HAProxy's health check is the liar.
- Read the stats to see who is DOWN and whyEnable the stats page (`stats enable`) or query the socket: `echo 'show servers state' | socat stdio /run/haproxy/admin.sock`. The check status column tells you L4CON (can't connect), L7STS/404 (wrong check path), or L7TOUT (check timed out) — each points at a different fix.
- Align the health check with a real endpointSet `option httpchk GET /healthz` and `http-check expect status 200` to a path that returns 200 without auth. A check pointed at `/` that 301-redirects to HTTPS counts as a failure unless you tell HAProxy to expect the 3xx. Reload and watch the server flip to UP.
- Verify the routing actually reaches a populated backendTrace the request's Host/path through your `acl` and `use_backend` rules. A typo in a backend name or an ACL that matches nothing falls through to a `default_backend` that may be empty. `haproxy -c -f /etc/haproxy/haproxy.cfg` validates syntax but won't catch logically empty pools.
- Check for connection/queue saturation under loadIf servers flap between UP and 503 only at peak, look at `maxconn` per server and the backend queue depth in stats. Raise limits, add servers, or fix the slow upstream that's holding connections open.
Stop it recurring
Pin health checks to a dedicated `/healthz` route that exercises real dependencies, and alert on HAProxy's `backend` UP-server count dropping to zero rather than waiting for 503s.
Related errors