---
summary: "Common ScaiDial issues and how to diagnose them \u2014 trunk sync errors,\
  \ carrier whitelisting, browser softphone problems, no-audio calls."
title: Troubleshooting
path: troubleshooting
status: published
---

## Trunk parks in `sync_status=error`

**Symptom.** You created or edited a trunk, but `sync_last_error` is set and `sip_trunk_id` is null.

**First check:** read the error message verbatim. livekit-sip's response usually tells you the real cause.

| Carrier response | Likely cause | Fix |
|---|---|---|
| `401 Unauthorized` | Wrong `sip_auth_username` or `sip_auth_password` | Verify the credentials on the carrier's portal; the value you paste is the one ScaiDial REGISTERs with |
| `403 Forbidden` | Source-IP whitelisting on the carrier rejects us | Send your carrier the egress IP from `GET /network-info` |
| `503 Service Unavailable` | Carrier upstream issue or our livekit-sip can't reach the address | Check `sip_server_address` resolves; try `POST /trunks/probe` to test without persisting |
| `408 Request Timeout` | Firewall is dropping our packets before they reach the carrier | Same as 403 — egress IP whitelisting is the usual fix |

After fixing the underlying cause, hit `POST /trunks/{id}/resync` — no need to recreate the trunk.

## "No synced outbound trunk" on click-to-call (422)

**Symptom.** The browser softphone shows "Your tenant has no synced outbound trunk."

**Cause.** Either no trunk exists for the tenant, or the only trunks are in `sync_status="error"` / `"pending"`.

**Fix.** Open `/scaidial/trunks` and look at the sync-status badges. Either create a trunk or fix the synced one with the table above.

## Calls ring but I can't hear anything

This is almost always one of three things.

**Browser mic permission denied.** Open the browser's permission panel for the site. Reload after granting. The softphone publishes the mic on join — if `getUserMedia` fails, the room connects but no audio is sent.

**Remote audio not autoplaying.** Some browsers block autoplay if there hasn't been a recent user gesture. The click that originated the call counts, but if the call was initiated by a different tab or in a background context, autoplay may be blocked. Hit "Hang up" then "Place call" again, fresh.

**SIP/RTP firewall.** If livekit-sip can't get RTP back from the carrier, the SIP leg connects but the media path is dead. Verify your firewall lets UDP 10000-10200 (the RTP range) in and out. `GET /network-info` shows the exact range.

## Inbound calls fail with "no_rule_matched"

**Symptom.** Inbound call arrives, immediately gets `end_reason=no_rule_matched`.

**Cause.** The dialplan has no rule that matches this call. Common reasons:

- All rules use `time_window` and the call is outside the window. Add an `always` fallback rule at priority 999.
- The DID isn't wired to the dialplan you edited. Check `GET /dids/{id}` and verify `dialplan_id`.
- The rule is `enabled=false`.

The dialplan engine logs the rules it evaluated and why each one didn't match. Look in the ScaiGrid structured logs for `scaidial_dialplan_no_match` with the call ID.

## Voicemail has no transcript

**Symptom.** The voicemail audio plays fine but `transcript` and `summary` are null.

**Cause #1.** Transcripts are opt-in per tenant. Go to `/scaidial/settings` and enable "Voicemail transcripts." Existing voicemails won't get transcripts retroactively; new ones will from the moment you enable.

**Cause #2.** The opt-in is on but the transcript hasn't materialised yet. ScaiEcho runs after the recording is finalised; it's a few seconds for short messages, longer for multi-minute messages.

**Cause #3.** ScaiEcho returned an error (most commonly: pyannote model not loaded on the inference node, which only affects diarization — plain transcripts should still work).

## Transfer fails with 409

**Symptom.** Clicking Transfer surfaces "transfer failed: ..." with status 409.

**Causes:**

- **Attended mode requested.** v1 only supports blind transfer. The admin UI defaults to blind.
- **Carrier rejected the REFER.** Not all carriers accept SIP REFER from the answering leg. Test with `POST /trunks/probe` and ask your carrier whether REFER is supported on outbound trunks.
- **Leg already ended.** The other party hung up between when the transfer button rendered and when you clicked. The Active Calls page auto-refreshes every 4s; the window is small.

## Browser softphone disconnects mid-call

The store retries once after a transient drop. If it doesn't recover, the call card flips to `error` state with the disconnect reason.

If you see `SERVER_SHUTDOWN`, the LiveKit server (not livekit-sip — the SFU) was restarted. Calls survive controller restarts but not LiveKit-server restarts.

If you see network-level disconnects without server shutdown, check your WebRTC posture. The softphone uses LiveKit's default ICE — STUN servers + TURN if configured. If your network blocks UDP entirely, you need to configure a TCP TURN server.

## "scaidial not initialized" 503

**Symptom.** Per-leg control routes return 503.

**Cause.** The module registry constructed the ScaiDial module but its `start()` lifecycle hook hasn't completed yet. This is a startup window of a few seconds; it should clear by itself.

If it persists, check ScaiGrid logs for `scaidial_start_failed` — common causes are missing LiveKit cluster config (`SCAIBOT_VOICE_LIVEKIT_URL/API_KEY/API_SECRET`) or a livekit-sip sidecar that's not running. The Trunks page is still readable in this state; you just can't act on calls.

## Where to look in the logs

ScaiDial emits structured (key=value) events. The most useful keys for triage:

- `scaidial_inbound_dispatch_decision` — every inbound INVITE, including the matched rule.
- `scaidial_outbound_originate` — every click-to-call (or other admin originate).
- `scaidial_leg_state_change` — leg state transitions; useful for figuring out where a call died.
- `scaidial_trunk_sync_failed` — the carrier's actual response, in full.
- `scaidial_livekit_sip_*` — anything wrong on the sidecar path.

Filter by `correlation_id` to follow a single call across components.
