Freeze the disputed request and exact query
Record timestamp and timezone, installed Asterisk branch and maintenance release, loaded module, endpoint, channel and unique identifiers, SIP method, Call-ID, CSeq, dialplan location, prefix argument, returned list and the expected name or value. Preserve a sanitized message when one exists.
Classify the first symptom: unknown function, empty list, prefix returns nothing, expected name missing, unexpected name present, repeated fields collapsed, wrong value read, wrong channel, non-INVITE expectation or consumer rejected an otherwise correct result.
Separate availability from an empty result
Confirm the running release meets the documented 16.20.0 or 18.6.0 floor and that res_pjsip_header_funcs is loaded. Verify the active channel is PJSIP. If the function is unavailable, correct the supported version or module boundary before interpreting any list.
If the function exists, keep troubleshooting at the message and channel layer. Reinstalling or changing endpoint policy does not explain a prefix mismatch or a query executed on a different request.
Prove the current message is the intended INVITE
Correlate the dialplan execution with the inbound INVITE by timestamp, Call-ID, CSeq and channel. REGISTER, OPTIONS, an outbound callee INVITE, a SIP response or a later in-dialog request is outside the documented inventory scope. Local channels, transfers and new outbound channels can move execution away from the original PJSIP request.
Do not use PJSIP_HEADERS() to prove what Asterisk emitted. Use the outbound-header workflow and a bounded wire capture for that question; use the response-header workflow for an answered outbound INVITE response.
Compare unfiltered and prefix-filtered lists
Run the same request through an unfiltered inventory and the smallest intended prefix. Preserve both literal results. If the name appears only in the complete list, correct the prefix or the consumer comparison rather than adding another header.
Apply SIP case-insensitive name comparison deliberately, and account for RFC 3261 compact forms where applicable. Do not silently rewrite unknown custom names or assume every downstream store preserves the same casing and separators.
Read values and repeated instances separately
A single inventory entry does not mean the INVITE contained one field row. Use PJSIP_HEADER(read,name,number) for the intended inbound value and explicit instance, then compare it with the sanitized request. Preserve ordering where the field definition makes it significant.
An empty selected value can mean the instance is absent even when the name exists. A present value does not validate its syntax, sender trust or suitability for routing, identity, emergency or billing logic.
Correct one boundary and repeat a control
Correct only the demonstrated boundary: supported release, loaded module, PJSIP channel, INVITE timing, prefix, name normalization, compact-name handling, instance number or consumer validation. Repeat the same authorized request and a control without the optional field.
Remove temporary full-header logging and retain only approved identifiers and values. Do not copy the inbound inventory wholesale to an outbound request or weaken endpoint identification to make a field appear. No PBX, module, dialplan, channel, request, header, endpoint, packet or call was inspected or tested for this diagnostic.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Asterisk PJSIP_HEADERS dialplan function ↗
- Asterisk PJSIP_HEADER dialplan function ↗
- 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.