Freeze one call and the intended ring set
Record timestamp and timezone, caller channel, dialplan context and priority, endpoint argument, optional AoR and request user, expected devices, timeout, actual Dial() argument, created outbound channels, per-leg SIP responses, winning channel and DIALSTATUS.
Classify the first divergence: wrong endpoint, wrong or missing AoR, empty contact set, stale or replaced contact, incomplete generated string, no outbound channel, one rejected leg, all legs failed, one answered and siblings were cancelled, or media failed after answer.
Resolve the endpoint-to-AoR relationship
Inspect the loaded endpoint and enumerate its configured AoRs. If the function supplies an explicit AoR, prove that object exists and contains the intended devices. If it omits the AoR argument, prove which endpoint AoRs the running system selects.
Do not infer ownership from a matching extension number, authentication username or device label. Endpoint, auth, AoR and contact are distinct PJSIP objects whose names can coincide without being the same object.
Enumerate current permanent and dynamic contacts
At the failing time, record the internal contact IDs returned for the AoR and inspect each sanitized URI, expiration, qualification state and Path data. Compare the set with registration events and the intended inventory.
If a contact vanished or another registration replaced it, evaluate max_contacts, remove_existing, remove_unavailable and expiry policy before changing the dial function. Do not add a static destination until the device lifecycle and authorization model support it.
Compare the generated string with created channels
Capture the exact PJSIP_DIAL_CONTACTS() return value and the value passed to Dial(). An empty result needs an explicit no-contact branch; a non-empty result should be compared destination by destination with the outbound channels Asterisk actually created.
Check for accidental extra PJSIP/ text, truncation, quoting, an unintended single-contact target, or a request-user override that changes routing. Redact addresses before sharing the trace.
Follow every leg until answer or final response
For each created channel, record INVITE destination, provisional response, final response or local failure and hangup cause. A contact answering first normally causes Dial() to cancel or hang up the sibling attempts; those cancellations do not show that only one contact was dialed.
If no leg answers, keep DNS, transport, authentication, routing, alerting and timeout evidence separate. OPTIONS reachability does not prove INVITE success, and registration does not prove that the device accepts this call identity or request URI.
Correct one boundary and repeat the same call
Correct only the earliest proven mismatch, reload through the supported process if configuration changed and repeat the same bounded call. Preserve before-and-after contact IDs, generated string, outbound channels and per-leg results.
If one device answers, verify that the other legs ended for the expected first-answer reason. If audio then fails, move to the media diagnostic rather than rewriting contact selection. This diagnostic is documentation-derived; no PBX, registration, contact, device, channel or call was inspected or tested.
Carry each contact attempt through the core Dial lifecycle
The Dial application guide adds application timing, final status, losing-leg causes, answer, bridge and continuation evidence.
Check the dial-group read before contact expansion
When DIALGROUP supplies the endpoint or interface, the dial-group diagnostic proves membership and exact readback before this contact-level trace.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Asterisk PJSIP_DIAL_CONTACTS function ↗
- Asterisk Dial application ↗
- Asterisk PJSIP_AOR function ↗
- Asterisk PJSIP_CONTACT function ↗
- Asterisk PJSIP configuration relationships ↗
- Asterisk AMI PJSIPShowAors action ↗
- Asterisk AMI PJSIPShowEndpoint action ↗
- Asterisk 22 Dial application ↗
- Asterisk pre-dial handlers ↗
- Asterisk hangup-cause overview ↗
- Asterisk HANGUPCAUSE_KEYS function ↗
- Asterisk CHANNEL function ↗
- Asterisk DIALGROUP dialplan function ↗
- Asterisk HANGUPCAUSE dialplan function ↗
- Asterisk HangupCauseClear application ↗
- Asterisk command-line interface ↗
- Asterisk func_dialgroup implementation ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.