try hiccup

Q.850 cause codes

Short version: Q.850 is the PSTN's vocabulary for why a call ended; SIP status codes are a lossy translation of it, made at the gateway by RFC 3398's table. The original cause, if you are lucky, rides along in a Reason: Q.850;cause=… header. The cause is the evidence; the status is the paraphrase.

Where Q.850 appears in SIP

ITU-T Q.850 defines the cause values carried in ISUP REL and Q.931 DISCONNECT messages — the PSTN's entire language for "why this call is over". The two vocabularies do not line up: Q.850 has over a hundred causes, SIP a few dozen relevant statuses, so a gateway has to translate. RFC 3398 is the dictionary; the tables below are its defaults.

Because the translation loses detail in both directions, SIP grew a way to carry the original alongside it: the Reason header of RFC 3326, as in Reason: Q.850;cause=34;text="No circuit/channel available". You will meet it on BYE and CANCEL requests, and — since RFC 6432 made it explicit — on final responses too. One message may carry two Reason values, one SIP and one Q.850: the same event described from both sides of a gateway.

This is why the Reason header outranks the status code. A bare 503 might be nothing more than your own SBC's overload control; a 503 carrying Reason: Q.850;cause=34 was minted from a real ISUP release behind the trunk, by the network that actually failed.

The full cause-to-SIP mapping table

This direction answers "the carrier released with cause N — what status will my SIP leg see?". These are RFC 3398's defaults; almost every SBC and gateway exposes an override table, so a trace that disagrees with this one is configured, not broken.

CauseQ.850 nameSIP response
1Unallocated (unassigned) number404 Not Found
2No route to specified transit network404 Not Found
3No route to destination404 Not Found
16Normal call clearing— (a BYE or CANCEL, not a status)
17User busy486 Busy Here
18No user responding408 Request Timeout
19No answer from user (user alerted)480 Temporarily Unavailable
20Subscriber absent480 Temporarily Unavailable
21Call rejected403 Forbidden (603 Decline when the user rejected)
22Number changed410 Gone (301 Moved Permanently when the new number is in the diagnostic)
23Redirection to new destination410 Gone
26Non-selected user clearing404 Not Found
27Destination out of order502 Bad Gateway
28Invalid number format (address incomplete)484 Address Incomplete
29Facility rejected501 Not Implemented
31Normal, unspecified480 Temporarily Unavailable
34No circuit/channel available503 Service Unavailable
38Network out of order503 Service Unavailable
41Temporary failure503 Service Unavailable
42Switching equipment congestion503 Service Unavailable
44Requested circuit/channel not available503 Service Unavailable (see note)
47Resource unavailable, unspecified503 Service Unavailable
55Incoming calls barred within CUG403 Forbidden
57Bearer capability not authorized403 Forbidden
58Bearer capability not presently available503 Service Unavailable
65Bearer capability not implemented488 Not Acceptable Here
70Only restricted digital bearer capability available488 Not Acceptable Here
79Service or option not implemented, unspecified501 Not Implemented
87User not member of CUG403 Forbidden
88Incompatible destination503 Service Unavailable
102Recovery on timer expiry504 Server Time-out
111Protocol error, unspecified500 Server Internal Error
127Interworking, unspecified500 Server Internal Error

Cause 44 is the one entry above that RFC 3398 does not enumerate by name: gateways map it, with the rest of the resource-unavailable class, to 503 — where the whole congestion family ends up anyway.

The reverse direction — the cause a gateway writes into the ISUP REL when the SIP leg says no — is also defined by RFC 3398:

SIP response receivedQ.850 cause in the REL
400 Bad Request41 Temporary failure
401 Unauthorized21 Call rejected (only after authentication actually failed)
402 Payment Required21 Call rejected
403 Forbidden21 Call rejected
404 Not Found1 Unallocated number
405 Method Not Allowed63 Service or option unavailable
406 Not Acceptable79 Service or option not implemented
407 Proxy Authentication Required21 Call rejected (only after authentication actually failed)
408 Request Timeout102 Recovery on timer expiry
410 Gone22 Number changed
413 Request Entity Too Large127 Interworking, unspecified
414 Request-URI Too Long127 Interworking, unspecified
415 Unsupported Media Type79 Service or option not implemented
416 Unsupported URI Scheme127 Interworking, unspecified
420 Bad Extension127 Interworking, unspecified
421 Extension Required127 Interworking, unspecified
423 Interval Too Brief127 Interworking, unspecified
480 Temporarily Unavailable18 No user responding
481 Call/Transaction Does Not Exist41 Temporary failure
482 Loop Detected25 Exchange routing error
483 Too Many Hops25 Exchange routing error
484 Address Incomplete28 Invalid number format
485 Ambiguous1 Unallocated number
486 Busy Here17 User busy
488 Not Acceptable Herederived from the Warning header when present
500 Server Internal Error41 Temporary failure
501 Not Implemented79 Service or option not implemented
502 Bad Gateway38 Network out of order
503 Service Unavailable41 Temporary failure
504 Server Time-out102 Recovery on timer expiry
505 Version Not Supported127 Interworking, unspecified
513 Message Too Large127 Interworking, unspecified
600 Busy Everywhere17 User busy
603 Decline21 Call rejected
604 Does Not Exist Anywhere1 Unallocated number
606 Not Acceptablederived from the Warning header when present

Put the two tables side by side and you can watch information being destroyed. Causes 34, 38, 41 and 42 all become 503, and a 503 crossing back into ISUP becomes 41 — so whichever member of the congestion family a cause started as, two gateways later it is "temporary failure". Only the Reason header survives the round trip — when the boxes in the middle are polite enough to copy it.

The causes you actually meet

Cause 16 is not an error

Cause 16, normal call clearing, means exactly what it says: somebody hung up. On a BYE it is routine teardown and belongs in no failure report — which does not stop a remarkable number of CDR tools counting it as one. It is the most common cause value in any healthy network.

The one place cause 16 deserves attention is on a call that was never answered. Usually the release was still normal — the caller abandoned and a CANCEL became that REL — but it can also be a far-end platform "politely" clearing a call it never intended to complete. The question is not "why cause 16?" but "who released, from which direction, how long after the call started?". The cause is innocent; the timing sometimes is not.

The congestion family: 34, 38, 42, 44

Four causes, one SIP status, four different problems. 34 — no circuit/channel available means full: every trunk on some segment of the route is in use. Capacity, transient, and an immediate retry — especially one the carrier can route differently — often succeeds. 42 — switching equipment congestion means the switch itself is overloaded: processing, not trunks. Same advice, but if it persists through quiet hours something is genuinely sick.

38 — network out of order is the serious one: not full, broken. Q.850 intends it for failures likely to last a while, so a burst of cause 38 is an outage signal, not a load signal. Retrying into it achieves nothing.

44 — requested circuit/channel not available is the odd sibling: a specific circuit was requested and refused. On ISUP that smells of a CIC state mismatch or glare (both ends seizing the same circuit at once); on a PRI, a channel-map disagreement. Unlike 34 it is usually configuration wearing a congestion costume — a trunk group that throws 44 repeatedly needs an audit, not a quieter hour.

What to check in the trace

  1. Search the whole dialog for Reason: headers — on the BYE, the CANCEL and the final response. A Q.850;cause= value beats any amount of inference from the status code.
  2. Note which direction the release travelled. Whoever sent the BYE, or the response carrying the cause, owns the network that holds the answer.
  3. Compare the status against the table above. A pair that breaks the RFC 3398 default — a 480 carrying cause 17, say — means a box in the path runs a custom mapping, and its configuration is now part of the investigation.
  4. A 503 with no Reason header may never have touched the PSTN: SBCs mint bare 503s for their own overload and licensing limits. Provenance first, meaning second.
  5. Watch for double translation. If the status arrived as 503 and the cause as 41, the original may still have been 34, 38 or 42 one network away.
  6. If you can see the ISUP or Q.931 side, read the cause's location field — "user", "local network" or "transit network" narrows down who rejected the call better than the cause value itself.

hiccup pulls the Reason header out of every BYE, CANCEL and final response, shows the Q.850 cause and its meaning next to the SIP status in the ladder, and flags the calls where the two tell different stories. Self-hosted, free for individual users.

upload a trace