Reader setup
Before you diagnose
Start with one observed symptom, then isolate one layer at a time.
- Reproduce the issue with one approved synthetic destination and record its exact test window.
- Use read-only access to the VICIdial/Asterisk logs and the installed Asterisk command-line interface (CLI).
- Save the deployed file hash and current logging level before evaluating any code or verbosity change.
- What you will prove
- You will tell a short channel-creation timing race from a permanently missing destination and document the smallest safe correction boundary.
- Safety boundary
- Do not select a global newest channel, capture unrelated calls, or deploy a retry from this article without source-pinned review and rollback approval.
Reader path
How to use this article
- Use it when: You are investigating a live symptom and need to narrow the failure quickly.
- Expected result: Pinpoint the first failing layer, then repair only that layer.
- Start here: Use the sections as a diagnostic sequence: prove scope, then isolate and validate.
Read the race in chronological order
Fast answer: an Asterisk Local channel can be visible before its bridged SIP destination is available to an AGI (Asterisk Gateway Interface) lookup. The resulting NO DestChannel message often describes timing, not a permanently missing call leg.
Two terms carry this whole article. A Local channel is an internal Asterisk call leg that exists only inside the server; Asterisk uses one to start dialing before the real outbound leg to the carrier exists, which is exactly why a lookup can run too early. AMI is the Asterisk Manager Interface, an event stream you can read to watch calls progress, and the three events used below are DialBegin when dialing starts, Newchannel when a new call leg appears, and BridgeEnter when two legs are joined into a conversation. Reading them in timestamp order is what turns a vague failure into a measured gap.
Align the AGI timestamp with AMI (Asterisk Manager Interface) bridge, DialBegin and Newchannel events. Millisecond ordering is more useful than a later channel snapshot because the missing mapping may exist only briefly.
VICIdial's own dialplan gives this race a specific, real first step worth naming: on our ViciBox 12 lab, the very first line most call paths run is an AGI call into agi://127.0.0.1:4577/call_log, served by a dedicated FastAGI process listening only on loopback. That lookup runs early, on purpose, to log the call before anything else happens to it — which is exactly the kind of early read that can outrun a Local channel's own destination mapping if the timing shifts even slightly.
See vicidial-terminology-for-complete-beginners for the rest of this glossary.
- Capture the Local channel name and unique ID.
- Locate DialBegin, Newchannel and BridgeEnter events for the same call.
- Measure the gap between the first lookup and destination creation.
Visual walkthrough
Follow three real demo screens
Captured on an isolated VICIdial demo: Administration screens on September 24, 2026, and the idle Agent screen on August 11, 2026. Each caption states its own capture time, and every sanitized image helps you recognize a related screen; none proves that this article's call, command, or result occurred.Find carrier administration

Open Carrier Listings

Check the allowed SIP-stack setting

Build a three-line timeline before proposing a fix
Copy only the synthetic call's timestamps and opaque test token into a small worksheet. Do not publish complete AMI events: they can contain numbers, channel names and routing details.
The example below shows interpretation, not a measured production value. A destination appearing just after lookup supports a bounded-retry hypothesis; no destination event at all points to routing or originate failure instead.
Three rows is a floor, not a ceiling. If your own capture shows a second lookup, a second Newchannel, or a Hangup arriving before the bridge, add that row rather than forcing the evidence into a shape that fits only the three-step story below — a timeline that omits an inconvenient event is worse than no timeline at all.
12:00:00.100 AGI lookup destination = missing12:00:00.132 Newchannel event destination = owned test leg12:00:00.141 Bridge event local + destination joined Observed gap: 32 ms (illustrative only)This sample is a template or reading aid, not a terminal command. There is no output to show.
- Before you run it
- Replace the illustrative times with three sanitized timestamps from one approved synthetic call. Keep the same call token across every row and omit phone numbers, customer data and complete channel strings.
- Success looks like
- The rows form one unambiguous chronological story and show whether a destination appeared after the original lookup.
- Stop if
- Stop if events cannot be correlated to one call, clock sources disagree, or the destination never appears; a retry is not supported by that evidence.
Use a bounded mapping retry
If the destination appears immediately after the failed lookup, retry the mapping for a short bounded window. Keep the retry call-scoped and stop as soon as the unique Local leg maps to its destination.
Bounded means two concrete numbers, agreed before you write any code: a maximum attempt count and a maximum total wait, both small — the timeline above measured a gap in milliseconds, not seconds, so a retry loop that keeps trying for several seconds is not a narrow fix for this race, it is a new, slower failure mode wearing the old one's name.
Never choose the newest SIP channel globally. Concurrent calls make that shortcut unsafe and can attach optimization logic to another customer.
grep -c "NO DestChannel" /var/log/astguiclient/*.logasterisk -rx 'core show version'asterisk -rx 'core show help' | grep -i managerasterisk -rx 'manager show eventq'This sample changes a system, contacts an outside service, needs a live call, or would print real data from a shared server, so it was not run on the demo. Run it only where you are authorized, and compare the result with the success and stop guidance.
- Before you run it
- Run on the lab or approved affected server. grep -c only counts matching lines per file, so it never prints a real channel name, number or routing detail; confirm manager show eventq exists with core show help before relying on it, since it is version-dependent.
- Success looks like
- You get a per-file count of the exact synthetic NO DestChannel pattern and confirm the installed Asterisk version and manager-event support, without printing a single raw log line or changing runtime state.
- Stop if
- Stop if any command needs a broader log read than a count, if permissions are wider than expected, or if manager show eventq is unsupported on this build; do not improvise a state-changing substitute.
Prove the fix under concurrent calls
A single successful call is not enough. Run a controlled set with overlapping Local channels and confirm every mapping retains its own unique identifier.
Watch answer, bridge, hangup and recording behavior. The retry must close only the observed timing gap and must not change routing or disposition semantics.
Local channel names are not guaranteed unique-looking to a human at a glance — several can share the same base extension and differ only in a trailing sequence number. A retry that matches on the visible name instead of the channel's own unique identifier can silently pair the wrong two legs together the moment two calls overlap, which is a worse failure than the one you started with because it fails quietly instead of loudly.
- Test answered, busy, no-answer and early-hangup outcomes.
- Confirm no cross-call destination mapping appears.
- Keep a rollback copy and the exact deployed hash.
Rollback by hash and document the remaining unknowns
If a reviewed retry changes routing, call correlation, recording, disposition or CPU/log behavior, restore the exact prior file through configuration management and repeat the synthetic baseline. Do not hand-edit a second guess into the running dialer.
Record the source revision, old and new hashes, observed timing range, test outcomes and unsupported call paths. A lab timing result does not prove every carrier, Asterisk release or concurrent production pattern.
Name the unknowns explicitly rather than letting a passing lab test stand in for them: a different Asterisk release may schedule the same AGI lookup at a different point in its own dialplan processing, a busier production server may widen the observed gap under load instead of narrowing it, and a carrier with a slower initial response can change which side of the race a given call lands on. Write down which of these you have not yet tested, not just which you have.
- Restore the approved prior hash rather than reconstructing it from memory.
- Repeat answered, rejected, no-answer and overlapping synthetic calls.
- Escalate when correlation remains ambiguous or the destination never exists.
Primary references
Sources
- Local ChannelAsterisk · accessed September 23, 2026
- Asterisk Gateway Interface (AGI)Asterisk · accessed September 23, 2026
- Asterisk Manager Interface (AMI)Asterisk · accessed September 23, 2026
- call_log end_time NULL for Local channels + Recording channel not hanging up after disposition for manual callsVICIdial forum · accessed September 23, 2026