try hiccup

SIP 503 Service Unavailable

Short version: a 503 means "not me, not now" — the element that answered has no capacity or no service to offer, and is inviting you to try somewhere else. It says nothing about the user you dialled. Job one is working out which box generated it — a 503 is routinely minted by your own edge.

What a 503 actually claims

RFC 3261 section 21.5.4 defines 503 as the server being temporarily unable to process the request "due to a temporary overloading or maintenance of the server". Two properties do the work: the condition is temporary, and it is server-scoped, not user-scoped. The same section makes 503 as much a routing instruction as an error: a client receiving one SHOULD attempt the request at an alternate server, and SHOULD NOT send further requests to the server that refused for the duration given in Retry-After, if present.

Two footnotes matter. RFC 3261 also permits an overloaded server to simply drop the request, so the same fault often surfaces as a 408-shaped timeout instead. And a proxy is told not to forward a 503 upstream unless it cannot service any request at all — it should try elsewhere and, with every route exhausted, answer 500. Almost everybody relays them anyway, which is why the 503 in your CDR may have been born three hops away.

What actually causes it

Trunk capacity and rate caps

The most common source. SIP trunk providers enforce a concurrent channel count and a calls-per-second cap, and either one trips as a 503. Diallers ramping up, a queue overflowing to mobiles, the Monday 09:00 spike — anything bursty finds the CPS limit first. The signature is intermittent: 503s clustered inside a second or two, healthy calls in between, concentrated at busy hour.

Your own edge marking the carrier dead

SBCs and gateways keep peers alive with OPTIONS pings. When the pings fail, new calls toward that trunk are refused locally with a 503 — Cisco CUBE busying out a dial-peer on OPTIONS failure is the canonical example. That 503 arrives about as fast as physics allows and never crossed the WAN; the real fault is whatever broke the OPTIONS, minutes or hours earlier.

Session and resource limits on your own servers

FreeSWITCH answers 503 when max_sessions or its sessions-per-second throttle trips, with a reason phrase that says so. Kamailio deployments commonly emit 503 from pike or ratelimit protections. Cisco CUBE ties 503 to its call-admission thresholds — CPU, memory, total calls, call spike.

Maintenance and draining

Graceful-shutdown modes answer new INVITEs with 503 — often with a Retry-After — while established dialogs finish. If the 503s begin at an exact minute and stop at another exact minute, someone was deploying.

Genuine downstream congestion, gatewayed

On PSTN interconnects the congestion family of Q.850 causes — 34 (no circuit available), 38, 41, 42, 47 — maps to a 503 under RFC 3398, and the response often carries Reason: Q.850;cause=34 to prove it. Travelling the other way, a SIP 503 becomes cause 41, temporary failure.

Which element sent it

A 503 does not name its author, so you infer. Latency is the strongest clue: a millisecond or two after the INVITE means a local or first-hop verdict, while arriving after a 100 Trying means it travelled. The Server header and the reason phrase fingerprint many stacks — "Maximum Sessions Exceeded" is not a carrier talking. A Reason header carrying a Q.850 cause means a PSTN gateway is in the story. Best of all, capture both legs of your SBC: an ingress 503 with no corresponding egress INVITE means your SBC refused the call itself, usually a peer it has marked out of service; an egress INVITE answered 503 means it is relaying someone else's verdict.

Retry-After, and who honours it

Retry-After (RFC 3261 section 20.33) on a 503 states how long the sender expects to be out of service, and the receiver SHOULD NOT route new requests there for that period. Without the header, RFC 3261 says to treat the response like a 500 — a verdict on this transaction, no hold-down implied.

Real implementations are all over the map: some SBCs hold a peer down whether or not the header is present, some honour it precisely, many endpoints ignore it entirely. A single 503 carrying Retry-After: 300 can quietly amputate a working trunk for five minutes, while ignoring the header produces retry storms against a server that told you it was drowning. When "one failed call" became a multi-minute outage, the Retry-After value or your equipment's hold-down default is the amplifier. The longer-term fix for overload is RFC 7339's Via-header overload control, for elements that speak it.

What failover should do with a 503

RFC 3263 treats a 503 like a transport failure: the client SHOULD retry the request, with a new branch, on the next target from the DNS/SRV list. A 503 from one host of a properly published cluster should cost milliseconds, not the call. The same logic applies at trunk level — treat the gateway as unreachable and route-advance.

Two cautions. Do not retry the same host — that is what Retry-After forbids and hold-downs exist for. And cap the hunt: if the true cause is your own CPS breach, machine-gunning the carrier's other POPs makes it worse. And a 503 to a mid-dialog re-INVITE fails only that transaction — per RFC 5057, only a 481 or 408 implies the dialog itself is dead; if the call dropped anyway, something chose to hang up.

503 vs 500 vs 480

500 Server Internal Error says something broke while processing this request — an exception, a misbehaving script. It makes no claim about capacity, and a retry against the same server may succeed. 503 says nothing broke: there is simply no service to give right now, go elsewhere. 480 Temporarily Unavailable is about the user, not the server — the server is fine, but the callee is unregistered, on DND or otherwise unreachable, so failing over to another server buys nothing. The boundaries blur: proxies convert 503 to 500 as RFC 3261 asks, and gateways map cause codes coarsely — treat all three as claims to verify, not verdicts to file.

What to check in the trace

  1. How fast the 503 arrived, and whether a 100 Trying preceded it — milliseconds with no provisional means a local verdict.
  2. The Server header and the reason phrase — many stacks sign their work.
  3. Retry-After: its value, and whether your side actually honoured it — did the next call to that peer route elsewhere?
  4. A Reason header with a Q.850 cause. 34 or 42 is real circuit congestion beyond the gateway, not a SIP-layer problem.
  5. The pattern in time: busy-hour clusters point at capacity, a hard start and stop at maintenance or a peer marked down, sub-second bursts at a CPS cap.
  6. OPTIONS to the same peer around the same timestamps — if the keepalives were failing too, the call is a bystander.
  7. Whether failover fired: was the next SRV target or trunk tried at all, and did every target answer 503 (an account or capacity problem) or only one host?

hiccup tells you which leg a 503 appeared on, how fast it came back, what the Retry-After asked for and whether failover actually stepped to the next target — as findings, next to the ladder. Self-hosted, free for individual users.

upload a trace