If you have ever stared at a SIP trace from an interworking gateway and seen a 503 Service Unavailable come back from the far side, you have already met the lossy edge of the PSTN-to-SIP boundary. That 503 was almost certainly a Q.850 cause value on the TDM/SS7 side - congestion, temporary failure, or "network out of order" - that got squashed into a single SIP response code on its way out of the gateway. Without the right header, you have no way to tell which one.

This is the territory of RFC 3398 - ISUP to SIP Mapping - together with ITU-T Q.850 (the cause value definitions) and RFC 3326 (the SIP Reason header field). Read together, the three documents tell you exactly what the gateway is supposed to do, where the mapping is one-to-many and therefore lossy, and how to keep the original Q.850 cause visible end-to-end on the SIP side. If you work anywhere on the carrier-to-IP boundary - SBC, media gateway, hosted PBX trunk, IMS interconnect - this is the mapping that actually shows up in your traces.

The Q.850 cause value, briefly

A Q.850 cause information element carries four pieces of data: a coding standard (CCITT, ISO/IEC, national, or standard-specific), a location (where in the network the cause was generated - user, private network, public network local user, transit network, public network remote user, international network, network beyond interworking point), a cause class + cause value combined into a single 7-bit number, and a diagnostic field that some causes use for extra context (the rejected bearer capability, the offending invalid call reference, and so on).

The 7-bit cause value is what people loosely call "the cause code." Q.850 organises it by class, where the upper 3 bits give the class and the lower 4 the value within the class:

  • Class 0 (causes 1-15) - normal events related to the called number itself: unallocated number, no route to destination, send special information tone, misdialled trunk prefix.
  • Class 1 (causes 16-31) - normal call clearing events: normal clearing, user busy, no user responding, no answer from user, subscriber absent, call rejected, number changed.
  • Class 2 (causes 32-47) - resource unavailable: no circuit available, network out of order, temporary failure, switching equipment congestion, access information discarded, requested circuit not available.
  • Class 3 (causes 48-63) - service or option not available: quality of service unavailable, requested facility not subscribed, incoming calls barred, bearer capability not authorised, bearer capability not presently available.
  • Class 4 (causes 64-79) - service or option not implemented: bearer capability not implemented, channel type not implemented, requested facility not implemented, only restricted digital information available, service or option not implemented unspecified.
  • Class 5 (causes 80-95) - invalid message: invalid call reference, identified channel does not exist, suspended call exists but call identity does not, no call suspended, message type non-existent, mandatory information element missing.
  • Class 6 (causes 96-111) - protocol error: information element non-existent, invalid information element contents, message not compatible with call state, recovery on timer expiry, parameter non-existent.
  • Class 7 (causes 112-127) - interworking: interworking unspecified.

The class is what tells you "which kind of bad" before you even read the value. A cause 41 (temporary failure) and a cause 47 (resource unavailable, unspecified) are both class 2 - resource problem, not a routing problem and not a far-end refusal. A cause 21 (call rejected) and a cause 17 (user busy) are both class 1 - normal events, not a network or equipment problem. The class hint is useful when you are reading a trace that has been mangled into a generic SIP 503: if you can recover the Q.850 cause via the Reason header, the class alone often tells you whether to look at routing, the far-end subscriber, the network itself, or a service-policy decision.

The canonical ISUP → SIP mapping (RFC 3398 §7.2.4)

When a media gateway receives an ISUP REL (Release) message with a Q.850 cause and needs to terminate the SIP leg with an appropriate response, RFC 3398 §7.2.4 specifies which SIP response to use. The table below is the subset you will actually see in production traces - the full table covers every Q.850 cause but most of the rest are too rare to memorise.

Q.850 cause Description SIP response Notes
1 Unallocated number 404 Not Found The cleanest one-to-one mapping in the whole table.
2 No route to specified transit network 404 Not Found Usually surfaces in international interconnect.
3 No route to destination 404 Not Found
16 Normal clearing (BYE) Not a response - issued during the call, not at setup.
17 User busy 486 Busy Here
18 No user responding 408 Request Timeout The user agent didn't respond within timer T303/T310.
19 No answer from user (alerted) 480 Temporarily Unavailable The phone rang; the user didn't pick up.
20 Subscriber absent 480 Temporarily Unavailable Mobile-network roaming/registration variant of 19.
21 Call rejected 603 Decline (or 403 Forbidden) RFC 3398 prefers 603; some gateways emit 403.
22 Number changed 410 Gone (or 301 Moved Permanently) If the new number is supplied in the ISUP message, the gateway should use 301 with a Contact: header for the new destination.
23 Redirection to new destination 410 Gone
26 Non-selected user clearing 404 Not Found
27 Destination out of order 502 Bad Gateway The far-end exchange is unreachable, not absent.
28 Address incomplete 484 Address Incomplete Overlap-receive failure on the PSTN side.
29 Facility rejected 501 Not Implemented
31 Normal, unspecified 480 Temporarily Unavailable The lazy default. Whenever you see 31, suspect that a downstream switch had a more specific cause and dropped it.
34 No circuit/channel available 503 Service Unavailable Trunk-group congestion.
38 Network out of order 503 Service Unavailable
41 Temporary failure 503 Service Unavailable The most common "something failed and we didn't say what" cause.
42 Switching equipment congestion 503 Service Unavailable
47 Resource unavailable, unspecified 503 Service Unavailable
55 Incoming calls barred within CUG 403 Forbidden
57 Bearer capability not authorised 403 Forbidden
58 Bearer capability not presently available 503 Service Unavailable
65 Bearer capability not implemented 488 Not Acceptable Here The gateway can't carry the requested codec/capability.
70 Only restricted digital information bearer capability available 488 Not Acceptable Here
79 Service or option not implemented, unspecified 501 Not Implemented
87 User not member of CUG 403 Forbidden
88 Incompatible destination 503 Service Unavailable
102 Recovery on timer expiry 504 Server Time-out
111 Protocol error, unspecified 500 Server Internal Error
127 Interworking, unspecified 500 Server Internal Error The "I have no idea what just happened" cause. Frequently masks a downstream protocol error that nobody bothered to translate.

Two patterns to commit to memory:

  • Almost every "resource" cause (class 2) collapses to 503. Causes 34, 38, 41, 42, 47, 58, 88 - they all become 503. If you see a 503 from an interworking gateway, you know it was some class-2 cause; you do not know which without the Reason header.
  • Almost every "service barred" or "not authorised" cause (class 3) collapses to 403. Causes 55, 57, 87 - they all become 403. Combined with the 503 collapse, these two facts mean a downstream gateway running RFC 3398 strictly will give you one of three responses (403, 488, or 503) for the entire class 2 + class 3 + class 4 range, with the genuine cause buried in a header.

The other direction: SIP → ISUP (RFC 3398 §8)

When a SIP-originated call needs to be terminated into an ISUP trunk and a SIP failure response arrives, the gateway has to map the SIP response code back to a Q.850 cause to put in the ISUP REL. The mapping is documented in RFC 3398 §8.2.1; here is the practical subset:

SIP response Q.850 cause Notes
400 Bad Request 41 (Temporary failure)
401 Unauthorized 21 (Call rejected)
403 Forbidden 21 (Call rejected)
404 Not Found 1 (Unallocated number)
405 Method Not Allowed 63 (Service/option unavailable, unspecified)
406 Not Acceptable 79 (Service or option not implemented)
407 Proxy Authentication Required 21 (Call rejected)
408 Request Timeout 102 (Recovery on timer expiry)
410 Gone 22 (Number changed) - without diagnostic
413 Request Entity Too Large 127 (Interworking)
414 Request-URI Too Long 127 (Interworking)
415 Unsupported Media Type 79 (Service or option not implemented)
416 Unsupported URI Scheme 127 (Interworking)
420 Bad Extension 127 (Interworking)
480 Temporarily Unavailable 18 (No user responding)
481 Call Leg/Transaction Does Not Exist 41 (Temporary failure)
482 Loop Detected 25 (Exchange routing error)
483 Too Many Hops 25 (Exchange routing error)
484 Address Incomplete 28 (Address incomplete)
485 Ambiguous 1 (Unallocated number)
486 Busy Here 17 (User busy)
487 Request Terminated (no mapping - call cancelled) The originating side sent CANCEL before the call was answered; on the ISUP side the gateway sends REL with cause 16 (normal clearing) or no cause if the call was never answered.
488 Not Acceptable Here 31 (Normal, unspecified)
500 Server Internal Error 41 (Temporary failure)
501 Not Implemented 79 (Service or option not implemented)
502 Bad Gateway 38 (Network out of order)
503 Service Unavailable 41 (Temporary failure)
504 Server Time-out 102 (Recovery on timer expiry)
505 Version Not Supported 127 (Interworking)
580 Precondition Failure 47 (Resource unavailable, unspecified)
600 Busy Everywhere 17 (User busy)
603 Decline 21 (Call rejected)
604 Does Not Exist Anywhere 1 (Unallocated number)
606 Not Acceptable 31 (Normal, unspecified)

The SIP-to-ISUP direction is also lossy - 403 collapses to cause 21, 404 collapses to cause 1, 503 collapses to cause 41. If you have a SIP origination that the user wants you to debug and the only artefact is the ISUP REL the far side reports having received, you cannot reliably reconstruct the original SIP failure. (You can sometimes infer it from the location code, but the cause value alone is not enough.)

The Reason header: how to keep the original cause visible (RFC 3326)

The lossiness of the basic mapping is exactly why RFC 3326 exists. The Reason header field carries a structured cause description through the SIP signalling, with both Q.850 and SIP namespaces, so a downstream proxy or B2BUA can read the original Q.850 cause even when the SIP response code itself has been compressed.

Two examples - first the ISUP-originated direction:

SIP/2.0 503 Service Unavailable
            Via: SIP/2.0/UDP gw1.example.net:5060;branch=z9hG4bK-abc
            From: <sip:+15551234567@example.net>;tag=A1
            To: <sip:+15559876543@example.net>;tag=B2
            Call-ID: 9c0e3a@example.net
            CSeq: 1 INVITE
            Reason: Q.850 ;cause=42 ;text="switching equipment congestion"
            Content-Length: 0
            

The basic SIP response is 503 per RFC 3398 §7.2.4. The Reason header preserves the actual Q.850 cause (42 - switching equipment congestion), so an upstream node can distinguish congestion from temporary failure or no-circuit-available even though the response code is the same in all three cases.

Second example - the SIP-originated direction with a CANCEL:

CANCEL sip:+15551234567@example.net SIP/2.0
            Via: SIP/2.0/UDP ua1.example.net:5060;branch=z9hG4bK-xyz
            From: <sip:+15559876543@example.net>;tag=A1
            To: <sip:+15551234567@example.net>
            Call-ID: 9c0e3a@example.net
            CSeq: 1 CANCEL
            Reason: SIP ;cause=200 ;text="Call completed elsewhere"
            Content-Length: 0
            

This is the canonical use of the SIP namespace inside the Reason header. The cancel reason cause=200 ;text="Call completed elsewhere" (RFC 3326 §3) lets parallel-fork participants distinguish "the originator got bored and hung up" from "another fork already won the race" - useful when the surviving SIP UA needs to render a sensible call log.

A few practical points about Reason:

  • It is informational, not authoritative. The basic SIP response code still drives transaction matching, retry behaviour, and fallback routing on every intermediate node. Reason is a hint for human operators and for billing/CDR systems.
  • Multiple Reason headers are allowed. A response can carry both a Reason: Q.850 ;cause=N and a Reason: SIP ;cause=N simultaneously when an interworking gateway wants to surface both views.
  • It survives a fair number of B2BUAs unchanged. Sensible SBC implementations propagate Reason end-to-end. Less sensible ones strip it. If you are debugging through an unknown SBC and the Reason is missing, capture on both legs to confirm which node is responsible.

SIP-T and SIP-I: full ISUP encapsulation (RFC 3372 / RFC 3204)

For carrier-grade interconnect - particularly for tandem switches that need to preserve the entire original ISUP signalling end-to-end across a SIP transit - RFC 3398's cause-and-Reason mapping is not enough. The full ISUP message has fields (calling-party category, transit network selection, charge information, generic numbers, redirection counter) that no SIP header captures. The solution is SIP-T (RFC 3372 - Session Initiation Protocol for Telephones (SIP-T): Context and Architectures), which uses the application/ISUP MIME type registered by RFC 3204 (MIME Media Types for ISUP and QSIG Objects) carried inside a multipart/mixed body (RFC 2046) alongside the SDP.

A typical SIP-T INVITE looks like this in outline:

INVITE sip:+15551234567@gw1.example.net SIP/2.0
            ...
            Content-Type: multipart/mixed; boundary="boundary42"

            --boundary42
            Content-Type: application/sdp

            v=0
            o=user1 53655765 2353687637 IN IP4 198.51.100.10
            ...

            --boundary42
            Content-Type: application/ISUP; version=itu-t92+; base=itu-t92+
            Content-Disposition: signal; handling=optional

            ... raw binary ISUP IAM ...

            --boundary42--
            

SIP-I is the ITU-T variant of the same idea (Q.1912.5), and is the form used in IMS interconnect. Both rely on RFC 3204's MIME registration; the differences between them are mostly in which ISUP variant is encapsulated and how strictly the gateway is required to render the full ISUP into SIP headers in addition to attaching the body. For our purposes - a field engineer reading a trace - the key fact is that when a tandem-grade gateway carries SIP-T or SIP-I, you can decode the embedded ISUP message directly in Wireshark (which has an ISUP dissector), and you do not have to rely on the cause-mapping summary in the SIP response. The original Q.850 cause is right there in the encapsulated REL.

The reverse is not true: an originating SIP UA does not generally produce an ISUP body. SIP-T is a transit feature, not a UA feature. So you will see SIP-T bodies on call legs that traverse a class-4 tandem and not on legs that originate from a UCaaS softphone.

What to look for in a real trace

A few patterns from production capture review that go directly to the mapping:

  • A response of 503 Service Unavailable with no Reason header from a media gateway. The gateway is RFC 3398-compliant on the basic mapping but is not emitting Reason. You have lost the original Q.850 cause. If this is happening repeatedly, the gateway's Reason emission is misconfigured, or it is sitting behind an SBC that strips Reason.
  • A response of 480 Temporarily Unavailable with Reason: Q.850 ;cause=31. The downstream switch had no specific information; it sent cause 31 (normal, unspecified) and the gateway dutifully mapped 31 to 480. There is no useful information here. Treat it as a black box and look at the next hop downstream.
  • A 486 Busy Here with Reason: Q.850 ;cause=17 from a call to a mobile. Real busy. The mobile network reported the subscriber on a call. (Distinguish from cause 18/19 - those are alerted/no-answer, mapped to 408 and 480.)
  • A 503 Service Unavailable with Reason: Q.850 ;cause=34. Trunk congestion at a specific exchange. If you see this clustered in time-of-day patterns, it is a sized-trunk capacity issue, not a fault.
  • A 503 Service Unavailable with Reason: Q.850 ;cause=42. General switching equipment congestion. Different from cause 34 (which is specific to the trunk group); cause 42 is exchange-wide. Larger problem.
  • A 404 Not Found with Reason: Q.850 ;cause=1 for a number you know exists. The originating side number-translation failed before the call hit the destination exchange. Look at the dial-plan / least-cost-routing on the originating gateway.
  • A 403 Forbidden with Reason: Q.850 ;cause=21. The far end actively rejected the call. Different from cause 17 (busy) - cause 21 is "this user does not want this call right now." Frequent in nuisance-call-blocker deployments.
  • A 500 Server Internal Error with Reason: Q.850 ;cause=127. Interworking, unspecified - the maximum-uncertainty cause. The downstream gateway encountered something it couldn't map cleanly. The cause carries no diagnostic value; you have to capture upstream.

The general rule: always read Reason first. If Reason is present, the basic SIP response code is for the protocol machinery; the Reason is for you. If Reason is missing on an interworking call, that is itself a finding - capture both legs and confirm which node stripped it.

Closing the loop

ISUP-to-SIP mapping is one of those pieces of carrier engineering that nobody is taught and everybody is expected to know. Engineers who can read both directions of the table fluently - who know that a 503 is class 2 of something, that a Reason: Q.850 ;cause=42 is exchange congestion not trunk congestion, and that a SIP-T body on a transit leg can be decoded directly in Wireshark - diagnose carrier interconnect problems in minutes that would take an hour for an engineer working from the SIP side alone.

SIP Train's SIPT-301 - SS7, SIGTRAN, and Legacy Interworking course (the first course on the CCVE certification track) covers RFC 3398, Q.850, RFC 3326 (Reason), and the SIP-T/SIP-I encapsulation pattern in full detail, with annotated traces from carrier interconnect, IMS interconnect, and hosted-PBX trunk scenarios. If your work crosses the PSTN-to-IP boundary - and most carrier and UCaaS engineering does - SIPT-301 is built for you.

SIPT-301 covers ISUP-to-SIP, Q.850, and SIP-T/SIP-I in depth

SS7, SIGTRAN, and Legacy Interworking is the first course on the CCVE certification track. It covers RFC 3398, Q.850, RFC 3326, and the SIP-T/SIP-I encapsulation pattern in full detail, with annotated traces from carrier interconnect, IMS interconnect, and hosted-PBX trunk scenarios. If your work crosses the PSTN-to-IP boundary, this is the course built for you.

Browse the catalog View pricing