Freeze one failed transaction
Record the timestamp, dialed digits, selected trunk or endpoint, SIP method, destination, Call-ID, expected header name and expected value source. Save the peer's exact response and a sanitized working transaction if one exists. State whether the header is absent, duplicated, malformed, attached to the wrong method or present but ignored.
Do not start by adding the header in several contexts. One provider rejection can reflect routing, authentication, identity policy or message syntax even when its reason phrase mentions a header.
Map caller and callee channels
Follow the dialplan from the incoming or originating channel through Local channels, Queue or FollowMe paths and the final outbound PJSIP callee. Identify where the value is created, which channel owns it, and when the outbound channel comes into existence. A normal-context PJSIP_HEADER() call commonly targets the caller rather than the callee that sends the INVITE.
Inspect the active dialplan and one bounded verbose trace. In a FreePBX system, retain the GUI or module owner and the supported custom hook; a generated file that happens to contain the handler is not the source of truth.
Identify the header store and version boundary
If the design uses PJSIP_HEADER(), prove that a lowercase b pre-dial handler ran on each intended outbound channel and returned. If it uses PJSIP_INHERITABLE_HEADER(), confirm Asterisk is at least 20.19.0, 22.9.0 or 23.3.0 on the corresponding branch and prove the header was set before child creation.
Do not update or remove an inheritable header with PJSIP_HEADER(), or a direct header with PJSIP_INHERITABLE_HEADER(). The documented stores are separate. If both added the same name, remove the demonstrated duplicate through its owning function rather than clearing every custom header.
Check action semantics and message phase
add creates another instance. update requires the named instance to exist. remove affects headers previously added by the same function and can use a prefix match. Preserve the operation result, header number and value before retrying. Confirm that a From URI parameter is not being treated as a standalone header; PJSIP_HEADER_PARAM() currently supports parameters on From only.
If the missing evidence is in a 200 response, use the response-header path on the outbound channel at pre-connect time. PJSIP_HEADERS() enumerates names from an inbound INVITE and cannot prove what Asterisk emitted on the opposite leg.
Prove the smallest correction on and off target
Correct only the demonstrated owner: move the direct write to a callee pre-dial handler, add the required Return(), set an inheritable header before child creation on a supported version, remove one duplicate, or correct one provider-defined value. Preserve the prior dialplan and loaded state.
Repeat the failed call, verify the exact outbound request, response, answer and media separately, then run an unrelated route that must not receive the header. Remove captures and temporary logging. Do not forward arbitrary inbound headers, reusable tokens or asserted identities across trust boundaries. No PBX, dialplan, header, provider, endpoint or call was tested for this diagnostic.
Check the Gosub frame and handler channel before changing the header
The Gosub diagnostic distinguishes ordinary, caller pre-dial, callee pre-dial and pre-bridge execution. A correct subroutine log on the caller is not proof that the outbound PJSIP channel received the header.
Diagnose a missing From parameter separately
When the header exists but one From parameter is absent or in the wrong location, use the parameter diagnostic before replacing the whole header.
Diagnose inheritance before adding a second header copy
When a required field should propagate from a calling channel, follow the inheritable-header diagnostic before adding the same name through PJSIP_HEADER().
Do not confuse an inbound list with an outbound header
If the evidence comes from PJSIP_HEADERS(), use the inbound list diagnostic. A correct inbound inventory does not prove the callee INVITE carried a required field.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Asterisk PJSIP_HEADER dialplan function ↗
- Asterisk PJSIP_INHERITABLE_HEADER dialplan function ↗
- Asterisk PJSIP_HEADERS dialplan function ↗
- Asterisk PJSIP_HEADER_PARAM dialplan function ↗
- Asterisk PJSIP_RESPONSE_HEADER dialplan function ↗
- Asterisk pre-dial handlers ↗
- Asterisk dialplan subroutines overview ↗
- Asterisk Gosub guide ↗
- Asterisk 22 Gosub application reference ↗
- Asterisk 22 Return application reference ↗
- Asterisk STACK_PEEK function reference ↗
- Asterisk pre-bridge handlers ↗
- Asterisk 22 Dial application reference ↗
- Asterisk Dial application ↗
- Asterisk PJSIP_PARSE_URI_FROM dialplan function ↗
- Asterisk CHANNEL dialplan function ↗
- RFC 3261: SIP ↗
- Asterisk 20 PJSIP_INHERITABLE_HEADER reference ↗
- Asterisk 22 PJSIP_INHERITABLE_HEADER reference ↗
- Asterisk 23 PJSIP_INHERITABLE_HEADER reference ↗
- Asterisk res_pjsip header-function source ↗
- RFC 3261: SIP Session Initiation Protocol ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.