Hi everyone,
I’m running into a critical issue with Asterisk ARI that I haven’t been able to solve despite extensive debugging.
Setup:
- Asterisk 20.11 on CentOS 9
- Using ARI with a Python client (via
asterisk-arilib) - A callbot system that handles simultaneous calls
- Calls are managed in Stasis with recording, playback, and spying channels
Problem:
After ~10 to 20 minutes of normal operation under load, my ARI app starts failing to retrieve channels using:
client.channels.get(channelId=...)
This happens right after receiving a StasisStart event for that same channel. I log the channel ID from StasisStart, then immediately try to retrieve the channel to attach it to my internal state — and I get a 404 from the ARI API:
404 Client Error: Not Found for url: http://localhost:8088/ari/channels/<channel_id>
Even more confusing: the channel doesn’t appear in client.channels.list(), as if it never existed, even though StasisStart was just received.
This starts happening consistently after several minutes of high activity. Until then, everything works perfectly.
Observations:
- WebSocket seems still open — I never receive a disconnect event.
- My
client.run(apps="app_dialer")loop is in a background thread with auto-retry if it crashes (but I never see a crash). - I increased the
ulimit -nto 524288, so it’s not a file descriptor exhaustion. - Logging shows ~300 channels when this happens. Mostly
Snoop/channels, somePJSIP/. - I even tried adding up to 5 seconds of delay before retrieving the channel from ARI after
StasisStart, in case it was a race condition — it didn’t help.
Questions:
- Is there a hard ARI or Asterisk limit on channels or events per WebSocket client?
- Could some internal ARI channel registry be getting corrupted?
- Could “orphaned” Snoop channels be exhausting something internally?
- Any workaround that avoids losing control of in-progress calls?
My Dial Plan
[incoming]
exten => _X.,1,NoOp(Appel entrant reçu)
same => n,Answer()
same => n,Set(FULL_RECORD_PATH=/var/spool/asterisk/recording/full_call/${UNIQUEID}.wav)
same => n,MixMonitor(${FULL_RECORD_PATH})
same => n,Set(TALK_DETECT(set)=)
same => n,Stasis(app_dialer)
same => n,Hangup()
Any guidance or ideas would be greatly appreciated ![]()
Thanks in advance!