VEXYL AI

Troubleshooting

This chapter is a symptom index. Find what you see, check the listed item, and follow the link to the chapter section that holds the fix.

Where to look first

  1. Check that the gateway is up and read the licence and call counts:

    curl -s http://127.0.0.1:8081/health
  2. Read the last 200 log lines around the time of the problem. See Logs for where they live on a binary and on Docker.

  3. If the complaint is "slow", read the per-turn LATENCY line. See Measuring response time. It needs LOG_LATENCY=true.

No audio or one-way audio

What you see Likely cause Check this Fix
Call answers, nobody hears anything (SIP) RTP blocked by a firewall, or the address in the SDP is a private one behind NAT SIP_PUBLIC_ADDRESS is set to the public address; the RTP port range is open both ways Firewall, Gateway side
Caller hears the bot, bot never hears the caller NAT or firewall closes the inbound RTP; codec mismatch on the trunk Compare the codecs on the trunk with the gateway When it does not work
No call reaches the gateway (AudioSocket) Wrong port, or AUDIOSOCKET_HOST is 127.0.0.1 while Asterisk runs on another machine Port in the dialplan matches AUDIOSOCKET_PORT; the host is reachable from Asterisk Troubleshooting, Dialplan
Browser widget connects, no sound Microphone blocked, or the origin or key was rejected Close code and HTTP status in the browser console Troubleshooting, Close codes

Call connects, bot silent

What you see Likely cause Check this Fix
Caller hears the timeout message, or nothing, after speaking The AI brain is unreachable or too slow LITEBOT_API_URL or CUSTOM_LLM_URL answers from the gateway host When the AI is slow or fails
Caller hears the fallback greeting text only The brain failed on the first turn Log lines at the start of the call; the brain endpoint Greeting, AI brain
Brain replies in the log, but no audio plays The TTS provider key or voice was rejected, the turn fell to Google, and Google credentials are missing Provider key and GOOGLE_APPLICATION_CREDENTIALS Choosing a TTS provider, Google
Caller hears an error sentence read aloud The brain relayed its own error as the reply The brain's own logs When LiteBot relays an error

Bot cuts itself off or talks over the caller

What you see Likely cause Check this Fix
Bot stops mid-sentence with nobody speaking Its own voice leaks back from the handset and is taken as the caller Log line BARGE-IN: echo transcript ignored Not hearing itself
Bot stops, then carries on from where it stopped A false interruption was detected and playback resumed Log line BARGE-IN: false interruption Interrupting the bot
Background noise or hold music interrupts the bot Threshold too low for the line The noise settings for the call Noisy lines
Bot talks while the caller is still speaking Caller speech arrived while the bot was busy Log line STT: transcript held during Speech while the bot is busy, Held transcripts

Caller's short replies ignored

What you see Likely cause Check this Fix
A bare "yes" after the greeting gets no answer First-turn speech gate in the recogniser The transcript log line for that turn Short replies and quiet handsets
Several short replies arrive as one late transcript Handset stops sending audio while quiet, so the turn never closes The inbound frame figures on the transcript log line Short replies and quiet handsets
Reply spoken during a long answer is lost Held and replayed, or dropped as echo or a stale acknowledgement Log lines starting STT: for that turn Held transcripts
Noise-only turns never reach the bot The transcript sanity gate dropped them The gate settings What never reaches the bot

Wrong or no voice

What you see Likely cause Check this Fix
One language is silent or in another voice, the rest are fine (Google) The Google voice does not match the language, Google answers 400, and the turn fails over GOOGLE_VOICE_<LANG> for that language; a global voice name set for all languages Google
Sarvam turns sound like the Google voice The speaker id is not valid for the chosen model, Sarvam answers 400, and the cascade ends on Google SARVAM_TTS_MODEL, SARVAM_TTS_SPEAKER and SARVAM_TTS_SPEAKER_<LANG> Sarvam
One fixed phrase (greeting, goodbye) is always in the wrong voice A fallback render was cached under the wrong key Whether the phrase was ever spoken during a provider outage Purge that entry: The TTS cache, TTS cache API
Per-call voice or model is ignored tts_provider for the call names a different provider than the voice belongs to The call's session metadata Per-call voice and model, Session metadata

Clicks or gaps between sentences

What you see Likely cause Check this Fix
Sentence endings clipped, words missing at the tail Sarvam bulbul:v4-flash over the WebSocket stream drops the sentence tail SARVAM_TTS_STREAM_TRANSPORT Set it to http and purge cached Sarvam audio: Sarvam, The TTS cache
Sentences run together, or a click at the join Seam padding and edge fades off or too small TTS_SENTENCE_MIN_GAP_MS, TTS_SENTENCE_EDGE_FADE_MS Sentence streaming and seams
Pauses between sentences of a long answer Synthesis slower than playback; log line WARN: TTS starvation sentence N Provider and voice speed; how often the line appears Sentence streaming and seams, Tuning that is safe to touch
Audio stutters across every call at once The host froze; log line LOOP-LAG: <n>ms stall ended Host load, virtual machine pauses Logs

Replies slow

What you see Likely cause Check this Fix
Long wait before every answer The brain, or its tool calls, take long The llm column of the LATENCY line Measuring response time, When the AI is slow or fails
Wait grows only on turns that use tools Several hops inside the brain The llm column on tool turns against plain turns AI brain
Audio starts late after the text is ready The TTS provider is slow to first audio The tts column Choosing a TTS provider
Wait between the caller stopping and the bot starting Endpointing or a handset that stops sending audio The buffer and stt columns Short replies and quiet handsets, Choosing a recogniser

Call never hangs up

What you see Likely cause Check this Fix
The bot says goodbye but the caller's line stays open The gateway's hang-up message is lost in NAT on a long call Whether the PBX trunk sends keepalive options to the gateway (Asterisk-front trunk only; leave it off on a direct-bridge trunk) Customer PBX side, Connect your PBX to the trunk
Goodbye is cut off or the line drops late Audio is drained before teardown, up to a ceiling LLM_HANGUP_DRAIN_MAX_MS Ending the call
Active call count in /health stays above zero Calls that did not end cleanly The PBX call list against the gateway count Health and licence, Active calls and stats

Transfers fail

What you see Likely cause Check this Fix
ERROR: Transfer requested on a SIP call but only an HTTP TRANSFER_ENDPOINT is configured — set TRANSFER_SIP_URI (e.g. sip:7000@pbx) for REFER A SIP call needs a SIP target; the HTTP endpoint serves AudioSocket only TRANSFER_SIP_URI starts with sip: Transfer to a person
AudioSocket call asks for a person, nothing happens No endpoint, or the call's channel was never sent TRANSFER_ENDPOINT; the channel field in the session metadata Transfers, Send caller details first
Bot never offers a transfer Transfers switched off, or the brain never raises the flag TRANSFER_ENABLED=true; the brain's escalation flag Transfer to a person, Flags
The PBX refuses the transfer The target extension does not exist for the trunk context PBX log for the REFER Customer PBX side

Webhooks missing

What you see Likely cause Check this Fix
Nothing arrives at the receiver WEBHOOK_URL unset, or the receiver is unreachable Log line WARN: Lifecycle webhook [<event>] failed Lifecycle webhooks
Receiver on a private network never gets events The address check blocks private targets WEBHOOK_SSRF_CHECK Delivery rules
An event was lost once and never came again Webhooks are not retried Receiver availability at that moment Delivery rules
Signature never matches The receiver re-serialised the body before hashing Hash the raw body bytes Verifying the signature

Billing records stuck in pending or dead

What you see Likely cause Check this Fix
Records pile up under the pending folder BILLING_CDR_URL empty (store-only), unreachable, or answering with an error The URL, the auth settings and the receiver's status code Delivery and retries
Records in the dead folder The retry ladder was exhausted, or the receiver returned a client error The receiver's reply for one record Delivery and retries
Receiver fixed, old records still waiting Dead records need an explicit replay /health pending and dead counts Replaying records, Billing replay

Licence invalid after container recreate

What you see Likely cause Check this Fix
Falling back to FREE tier (4 concurrent calls) at boot The key does not match this machine: hostname or CPU count changed, for example after a container recreate with a new hostname GET /license; the hostname inside the container Pin hostname: in the compose file and ask Vexyl for a key for the new machine: Licence inside Docker, Licence
SIP call rejected due to concurrent limit: N/M The licence call cap is reached concurrentCalls in /health Health and licence, Capacity
AUTH: Blocked request from <ip> for <METHOD> <path> The caller's address is not in HTTP_ALLOWED_IPS The allow-list Access

Process restarts

What you see Likely cause Check this Fix
WARN: RTP port <n> in use by another process (...), retrying on a fresh port (<attempt>) The gateway RTP range overlaps the one a co-hosted Asterisk uses RTP_PORT_MIN, RTP_PORT_MAX against Asterisk's rtpstart and rtpend Do not let the RTP ranges overlap, Co-hosting Asterisk and the gateway
Container exits at once or loops A mounted folder the process cannot write to The container logs Logs
Process restarts under pm2 or systemd Crash; the last lines before the restart name the cause The last 200 log lines Logs, Run

What to send Vexyl

When you ask for help, send all of this in one message:

  • The time of the call, with its timezone.
  • The caller's number.
  • The DID that was called.
  • What the caller heard.
  • A log excerpt covering the call, a few lines either side.
  • The output of the health check shown at the top of this chapter.

Hosted customers: see Getting help.