Freeze one group read and one failed attempt
Record timestamp and timezone, installed Asterisk branch, loaded module and dialplan revision, context, extension and priority, caller channel identifiers, exact group name, intended members, last known replacement/add/delete owner, redacted DIALGROUP readback immediately before Dial, PJSIP endpoint and AoR where relevant, timeout, options, DIALSTATUS and next branch.
Classify the first divergence: function unavailable, wrong dialplan loaded, wrong group name, writer did not run, whole-list replacement erased a member, add/delete targeted a different interface string, contact expansion changed, list blank or malformed, Dial failed per target, or the fallback branch is wrong.
Prove the function and loaded writer before editing state
Use the Asterisk CLI to confirm the running system exposes DIALGROUP and that the active context and priority match the reviewed dialplan. Follow the exact writer that most recently touched the group and distinguish no-operation replacement from the write-only add and del forms.
Do not repopulate a guessed list as the first diagnostic step. That destroys evidence about the owner, lifecycle and operation that produced the symptom.
Compare intended membership with exact readback
Read the disputed group at the same decision point as the failed call and preserve a redacted value. Compare interface strings exactly, including technology, endpoint, resource and any separators. Confirm that delete used the same member representation previously added and that another path did not replace the entire list afterward.
The reviewed reference does not define persistence or concurrent-writer guarantees. A value observed after reload, restart or simultaneous edits requires evidence from that installed branch rather than an assumed lifecycle.
Resolve PJSIP membership versus live contacts
If a member depends on PJSIP_DIAL_CONTACTS, capture the endpoint, selected AoR, optional request user and redacted expansion at the failed attempt. The function returns a dial string for current contacts; it does not make a contact exist or stay reachable.
A stable DIALGROUP read can therefore feed a changing PJSIP dial string. Check the existing PJSIP contact diagnostic when one device or no device rings, and do not treat registration state as proof of successful signaling or media.
Trace Dial status and per-leg causes separately
Preserve the timeout and options passed to Dial(), the returned DIALSTATUS and the next executed priority. For a multi-leg attempt, record HANGUPCAUSE_KEYS and query each returned channel with HANGUPCAUSE for both technology-specific and translated Asterisk cause information. Redact customer identifiers and credentials.
Clear prior causes only at a known trace boundary. Do not collapse an empty list, invalid argument, unavailable endpoint, busy response, no answer and a wrong post-Dial branch into one generic DIALGROUP failure.
Correct the earliest owner and repeat the same trace
Correct only the earliest demonstrated boundary: loaded module, active priority, group name, writer, operation, member grammar, contact expansion, blank-list guard, Dial input or later branch. Keep a rollback, then repeat the same call plus one empty-list control and one unavailable-target control.
Restore temporary logging and confirm the original group lifecycle. No PBX, module, dialplan, group, endpoint, contact, channel, packet, media stream or live 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 DIALGROUP dialplan function ↗
- Asterisk Dial application ↗
- Asterisk PJSIP_DIAL_CONTACTS dialplan function ↗
- Asterisk HANGUPCAUSE_KEYS 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.