Troubleshooting: fan-out and upload errors
Two shapes of failure live on this page. A fan-out failure is one call that becomes several sends — an email blast to many recipients, a Verify send that cascades across channels, a conference that dials many legs — where some or all of the legs fail. An upload rejection never fans out at all: the file fails pre-flight validation before anything is stored or sent. Both leave you holding an error code that names the aggregate, not the cause; the cause is always on an individual leg or on the input.Step one: identify the boundary your call crosses
The fix lives on one side of the POST boundary, so decide which before touching anything:- Upload rejections are input errors.
INVALID_FILE_TYPE,MAGIC_BYTE_MISMATCH,FILE_TOO_LARGE,INVALID_AUDIO, andAUDIO_TOO_LARGEare returned before the file is accepted. Nothing was stored and nothing was sent — the boundary is your request payload, and the fix is in the file you send, not in the API. - Fan-out failures are per-leg errors wearing an aggregate jacket. A
wrapper code like
EMAIL_SEND_FAILED_ALLorALL_CHANNELS_FAILEDonly exists because individual legs failed underneath it. The boundary is the legs, and diagnostics start by reading the per-recipient or per-channel breakdown in the response, never by retrying the whole call. CONFERENCE_DIAL_PARTIALis neither an input error nor a failed call. It arrives on a successful201inside the response body asdata.partial_failure_code: the conference is live with the legs that connected, and the failed legs are listed for you to act on.
Decision table
For any of these, the response’s
meta.docs_url points at the per-code
anchor on the error code reference, which is
regenerated from the platform’s canonical registry — treat that page as
the code’s definition of record.
Retry-safety matrix
Retries are safe only when the cause is transient. Each row states when a retry is the right move and when it is wasted work:
A fan-out call that failed partway is not idempotent by accident — on
POST /messages, recipients inside the succeeded group were delivered,
so a whole-call retry re-sends to them. Retry only the failed recipients
(culled from details.per_recipient), never the full list.
Reading the tiered failure rows
A mixed email blast returns one envelope whose body already tells you which recipients need which fix. The shape:- 5xx rows (
EMAIL_SEND_FAILED) — provider-side or transient. Wait for the upstream to clear, then retry just those recipients. - 4xx policy rows (
RECIPIENT_OPTED_OUT, suppression, quiet hours) — tenant-owned compliance controls doing their job. Take the recipient out of the list, or resolve the consent state with the contact before re-sending. These rows never succeed on retry. - 4xx input rows (
INVALID_EMAIL) — fix the address; the retry with the same payload is deterministic.
ALL_CHANNELS_FAILED on Verify, one layer
down: each attempted channel is a row to read, and the first 4xx row in
the chain is the gate to fix.
When a partial conference dial is acceptable
CONFERENCE_DIAL_PARTIAL earns its keep exactly once you decide which legs
mattered. A bridge where seven of eight participants joined is usually a
usable meeting — proceed, and re-dial the missing leg from the dashboard or
POST /voice/conferences/:id/participants when the eighth person matters.
A two-party connect where one of two legs failed is not usable — cancel the
conference and re-create it once the leg’s cause (balance, quiet hours,
unreachable destination) is fixed. The per-leg codes on the roster come
from the same vocabulary as the
conference lifecycle failures
table.
See also
- Email channel — deliverability, sender setup, and the recipient-level gates an email blast can trip.
- Multi-channel fallback and DLR — how the verify fan-out walks its channel chain and where receipts land.
- Troubleshooting: conference lifecycle failures — per-leg conference states, SIP codes, and the room-level event flow.
- Error code reference — the generated definition of record for every code on this page.