Freeze one event contract and attempt
Record installed branch and maintenance release, producer type, module or dialplan location, exact event name and case, schema version, custom correlation key, safe headers, AMI action request and response where applicable, manager user, session identity, receive timestamps, parser output, storage writes and the separately observed business result.
Classify the symptom before changing code: no action response, accepted action but no event, dialplan path not reached, event absent for one consumer, missing fields, duplicate delivery, duplicate storage or a received event whose claimed outcome is false.
Prove that the producer reached emission
For an AMI producer, correlate the UserEvent action response with its ActionID; treat that as transaction evidence, not an event-field promise. For a dialplan producer, prove that execution reached UserEvent() with the expected expanded event name and body. Confirm app_userevent is available on the installed system.
Use a safe test contract and unique application correlation key. Do not add secrets or personal data merely to make the event easier to find.
Check USER delivery controls in order
The generated event is class USER. Confirm the manager user has appropriate read access, the login and current session masks admit the class, and configured plus dynamic filters retain the exact event. Event names are case-sensitive, so a filter or consumer comparison using different case can correctly produce silence.
Then inspect raw AMI message boundaries before the client parser. An action can succeed while its resulting event is withheld from a particular session.
Compare fields with the producer contract
For dialplan emission, the optional body uses comma-delimited key:value pairs and AMI exposes additional arguments as event lines. A delimiter, empty value, variable expansion or conflicting header name can therefore change what the consumer sees. Preserve the exact sanitized emitted form and raw received message.
Channel snapshot fields, when present, describe the channel context at emission. Join Uniqueid and Linkedid according to their documented meaning, but do not infer a final call state from a transient snapshot.
Locate duplication at the first repeated boundary
Compare producer logs, raw AMI frames, parser output and storage rows using the application correlation key. Two producer invocations, producer retry, two active manager consumers, reconnect overlap and a repeated database write are different faults. Make the storage operation idempotent for the event contract rather than deleting unexplained rows after the fact.
Do not assume Asterisk replays custom events after reconnect. If the consumer missed a transition, reconcile from the authoritative application state or a suitable bounded snapshot.
Verify the outcome at its owner
A received UserEvent proves only that this custom message reached this consumer. Check remote answer, bridge or transfer state, recording completion, media quality and business-system completion at their respective owners. Correct or version the event contract when its name overstates what the producer actually knows.
No PBX, module, dialplan, manager session, event stream, channel, bridge, endpoint, packet, media stream, business system 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 23 AMI UserEvent action ↗
- Asterisk 22 AMI UserEvent action ↗
- Asterisk 23 AMI UserEvent event ↗
- Asterisk 22 AMI UserEvent event ↗
- Asterisk 23 UserEvent dialplan application ↗
- Asterisk 22 UserEvent dialplan application ↗
- Asterisk AMI event filtering ↗
- Asterisk AMI command syntax ↗
- Asterisk Manager TCP/IP API ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.