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
- How fast the 503 arrived, and whether a 100 Trying preceded it — milliseconds with no provisional means a local verdict.
- The
Serverheader and the reason phrase — many stacks sign their work. Retry-After: its value, and whether your side actually honoured it — did the next call to that peer route elsewhere?- A
Reasonheader with a Q.850 cause. 34 or 42 is real circuit congestion beyond the gateway, not a SIP-layer problem. - 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.
- OPTIONS to the same peer around the same timestamps — if the keepalives were failing too, the call is a bystander.
- 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