Skip to main content
Version: 0.9.18

SIP termination causes and header limits

Use this reference when you interpret a call termination or prepare optional SIP headers. It owns the platform's cause mapping, its diagnostic headers and the optional-header limits. Transports, codecs and other protocol behavior are described in SIP signaling and media.

Cause values and SIP responses are different​

Delphi selects a platform cause, a SIP cause value, and a Q.850 cause value. The SIP cause appears inside the diagnostic Reason header. It is not necessarily the status code of the SIP message carrying that header. For example, a BYE request can carry a SIP cause value of 408 to explain an application timeout.

Platform causeSIP causeQ.850 causeMeaning
conversation_complete20016Normal application completion
bot_timeout408102Application/bot timeout
stt_error50341Speech recognition error
tts_error50341Speech synthesis error
internal_failure50041Internal failure
policy_rejected40321Policy rejection
unknown_number4041Unknown or invalid destination
busy48617Busy destination
handover20016Handover or transfer

The platform can select a cause explicitly or infer one from its application reason. Use the selected cause recorded for the call; do not diagnose the underlying fault from the numeric value alone. For example, STT and TTS failures share the same numeric values.

A call rejected because its inbound trunk is in maintenance never reaches the application, so it has no platform cause: the edge answers the INVITE with the trunk's configured response, by default 503 Service Unavailable (see trunk maintenance).

Diagnostic header formats​

For a platform termination or an in-dialog REFER, the generated SIP diagnostic value has this form:

Reason: SIP;cause=408;text="failover_bot_timeout"

For a new outbound transfer INVITE, Delphi generates X-Transfer-Reason instead of reusing the original dialog's Reason header:

X-Transfer-Reason: handover;sip-cause=200;q850-cause=16;text="agent_handover"

These are examples of generated headers, not instructions to override platform-owned signaling. A final response before a call is answered can also carry a platform Reason; there need not be a BYE in that path.

Diagnostic text has control characters replaced by spaces, repeated whitespace collapsed, and a maximum of 256 Unicode characters before quoting. Quotes and backslashes are escaped for the header value. Empty text falls back to the selected cause name.

The termination service also passes the selected Q.850 value to the telephony stack. Header generation and publication are separate from successful delivery to the peer. Use SIP diagnostics to verify the relevant call leg and capture point.

Default optional-header limits​

These limits apply to the platform's default optional-header budget. A carrier or intermediary can have stricter limits.

CheckDefault limitCounting rule
Optional headers47The 64-header model reserves 16 standard/platform headers and one platform Reason header
Header name128 charactersUnicode characters in the name
Header value4,096 charactersUnicode characters in the value; the line limit below also applies
Complete header line4,096 charactersName + : + value + CRLF
Combined optional names and values12,000 charactersSum of name and value lengths across the optional set
Estimated complete message65,000 charactersOptional complete lines plus a default 768-character platform reserve

The complete-line limit is tighter than the value limit: a 4,096-character value cannot fit in a 4,096-character line once the name and separators are included. These character-based checks are distinct from the separately measured UTF-8 byte count.

Two thresholds apply to the estimated complete message. Above 65,000 characters, the header set exceeds its budget. Above 1,300 characters, Delphi only shows a warning, because RFC 3261 recommends TCP for requests of that size when the path MTU is unknown. The warning does not reject the headers or select a transport. Check the actual transport and peer limits separately.

Protected headers and normalization​

Optional headers must not replace SIP routing, dialog, framing, or authentication headers. The protected names are Via, From, To, Call-ID, CSeq, Max-Forwards, Route, Record-Route, Contact, Content-Length, Content-Type, Content-Encoding, Content-Disposition, Authorization, Proxy-Authorization, Proxy-Authenticate, WWW-Authenticate, Refer-To and Referred-By, plus the platform's internal headers.

The final normalization handles names case-insensitively, removes protected headers, replaces invalid name characters, and removes control characters from values. Configuration validation can reject an invalid field before it reaches this stage. The platform-generated Reason is handled separately from the optional set.

Proxy-compatible header names​

Availability: from 0.9.18.

Optional header names may contain ASCII letters, digits, hyphen (-), period (.), underscore (_), plus (+) and tilde (~). This set is narrower than the SIP token grammar, because the SIP edge rejects some token characters in header names.

  • Configured headers: a name with any other character is rejected on save with the message Invalid SIP header name. Use "<suggested name>" instead. A protected name is rejected with This SIP header is managed by the platform; use a custom header name, and a repeated name with a duplicate-name message.

These rules concern names only. Printable values such as 50% or customer|context stay as sent, and empty values are allowed. Control characters in values are replaced. The protected-name, collision and budget rules above still apply.

Validation happens before dispatch; it does not show that the peer received the header. To confirm delivery for HangUp and Transfer, follow the peer evidence procedure.

If optional termination headers are invalid​

In the platform termination path, an optional-header set that exceeds its budget is dropped, and termination proceeds with the platform-generated signaling. Failure to publish the header intent is logged and does not deliberately keep the call connected. This does not guarantee that the downstream hangup succeeds or that the peer receives the diagnostic header.

Do not generalize this termination behavior into a rule that transfer validation ignores invalid input. Consult the action-specific contract for transfer requirements.

For configuration responsibilities, return to SIP and call handling. For a missing header or unexpected cause, follow SIP diagnostics.

An explicit transfer header override selects the action's header set rather than augmenting it. To configure transfer headers and methods, use call transfer.

The transfer execution path checks the resolved optional-header budget. An oversized set blocks transfer and emits transfer_blocked with code: sip_header_budget_exceeded; it does not dispatch a smaller transfer and silently discard arbitrary values. Check the resolved headers, including rule-generated headers, before retrying. Use SIP diagnostics to distinguish a blocked action from a dispatched request and the peer's eventual outcome.

Dispatch does not guarantee that an intermediary preserves the headers or that a downstream peer accepted the transfer.