> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: fan-out and upload errors

> Diagnose fan-out failures where every leg or channel fails (EMAIL_SEND_FAILED_ALL, ALL_CHANNELS_FAILED), partial ring on conference dial-out (CONFERENCE_DIAL_PARTIAL), and rejected uploads (INVALID_FILE_TYPE, MAGIC_BYTE_MISMATCH, FILE_TOO_LARGE, INVALID_AUDIO, AUDIO_TOO_LARGE).

# 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`, and
  `AUDIO_TOO_LARGE` are 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_ALL` or `ALL_CHANNELS_FAILED` only
  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_PARTIAL` is neither an input error nor a failed
  call.** It arrives on a successful `201` inside the response body as
  `data.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

| Code                      | Where it appears                                         | What it means                                                                                                                                                                                                                                                                                                                                  | First move                                                                                                                                                                                                                                                                                    |
| ------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EMAIL_SEND_FAILED_ALL`   | Error envelope on `POST /messages` (email)               | Every recipient in a multi-recipient email send failed, and the per-recipient failures carried mixed codes. The dashboard renders the full `details.per_recipient` breakdown (each `{ to, code, details }`). When every recipient failed with the same code you get that code verbatim instead, so treat this wrapper as "mixed failure modes" | Read each per-recipient `code` and fix by class: a provider-side 5xx, a 4xx policy block, or a bad recipient each has a different owner. See the [email channel guide](/channels/email)                                                                                                       |
| `ALL_CHANNELS_FAILED`     | 503 on `POST /verify/send`                               | Verify fan-out tried every channel on your profile (SMS → voice → email, or the chain you configured) and no channel succeeded                                                                                                                                                                                                                 | Pull the first failing leg and work it as that channel's own error — a non-delivering SMS leg, a `DELIVERY_FAILED` voice leg, an email bounce. The wrapper vanishes once one channel delivers. The cascade model is on [Multi-channel fallback and DLR](/concepts/multi-channel-dlr-fallback) |
| `CONFERENCE_DIAL_PARTIAL` | `data.partial_failure_code` on a successful `201` create | The conference room is live; one or more dial-out legs failed to connect and are flagged on the roster                                                                                                                                                                                                                                         | Treat the room as usable. Re-dial the failed legs with `POST /voice/conferences/:id/participants`, or cancel the leg if it is no longer wanted. Per-leg causes and the roster flow are on [conference lifecycle failures](/troubleshooting/conference-failures)                               |
| `INVALID_FILE_TYPE`       | Error envelope on a file upload                          | The uploaded file's MIME type or extension fails pre-flight validation for the endpoint you're calling                                                                                                                                                                                                                                         | Convert or pick a file of a type the endpoint accepts; check the endpoint's accepted-types list first                                                                                                                                                                                         |
| `MAGIC_BYTE_MISMATCH`     | Error envelope on a file upload                          | The file's magic-byte signature does not match its declared MIME — the content does not match its name. Common when a file was renamed across types, or when a screenshot was saved as `.jpg` but is actually PNG                                                                                                                              | Re-export the file from its source instead of renaming it, then re-upload                                                                                                                                                                                                                     |
| `FILE_TOO_LARGE`          | Error envelope on a file upload                          | The file exceeds the size cap for that endpoint                                                                                                                                                                                                                                                                                                | Compress or split before upload. The cap lives in the endpoint's description; every byte above it is refused, and there is no partial acceptance                                                                                                                                              |
| `INVALID_AUDIO`           | 400 on voice-biometrics enrollment / verify              | The audio payload is invalid: not WAV, empty, or corrupt                                                                                                                                                                                                                                                                                       | Send a valid, non-empty WAV. Confirm the encode completed — a truncated upload looks exactly like a corrupt file                                                                                                                                                                              |
| `AUDIO_TOO_LARGE`         | 400 on voice-biometrics enrollment / verify              | The clip exceeds the 30-second / 2 MB maximum                                                                                                                                                                                                                                                                                                  | Trim the clip; on a genuine voice sample the usable signal is seconds, not minutes                                                                                                                                                                                                            |

For any of these, the response's `meta.docs_url` points at the per-code
anchor on the [error code reference](/reference/error-codes), 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:

| Code                                                         | Retry?                                   | Rule                                                                                                                                                                                                                                   |
| ------------------------------------------------------------ | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EMAIL_SEND_FAILED_ALL`                                      | Yes, once upstream 5xx clears            | If the per-recipient codes are 5xx/timeout-shaped, retry after the provider recovers. If any leg's code is 4xx (invalid recipient, policy block), fix that leg first — a blind retry re-fails the same way and burns rate-limit budget |
| `ALL_CHANNELS_FAILED`                                        | Yes, after reading the first failing leg | Work the earliest failing channel as its own error, then re-send the verify. Retrying without reading the per-channel failures just re-walks the same chain                                                                            |
| `CONFERENCE_DIAL_PARTIAL`                                    | Not a retry — an add/cancel decision     | The room already exists; there is nothing to retry. Re-dial the missing legs via the participants endpoint, or leave them out                                                                                                          |
| `INVALID_FILE_TYPE`, `MAGIC_BYTE_MISMATCH`, `FILE_TOO_LARGE` | Never until the input validates          | The same bytes return the same code every time. Fix the file, then re-upload. Retries below the size cap are the only exception (a truncated upload can succeed on a clean resend)                                                     |
| `INVALID_AUDIO`, `AUDIO_TOO_LARGE`                           | Never until the input validates          | Same rule: re-encode or trim the clip first                                                                                                                                                                                            |

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:

```json theme={null}
{
  "error": {
    "code": "EMAIL_SEND_FAILED_ALL",
    "message": "All 4 recipients failed",
    "status": 500,
    "details": {
      "per_recipient": [
        { "to": "alice@example.com", "code": "EMAIL_SEND_FAILED" },
        { "to": "bob@example.com", "code": "RECIPIENT_OPTED_OUT" },
        { "to": "carol@example.com", "code": "INVALID_EMAIL" },
        { "to": "dana@example.com", "code": "EMAIL_SEND_FAILED" }
      ]
    }
  },
  "meta": {
    "request_id": "req_abc123"
  }
}
```

Three tiers, three owners:

* **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.

The same tiering applies to `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](/troubleshooting/conference-failures)
table.

## See also

* [Email channel](/channels/email) — deliverability, sender setup, and the
  recipient-level gates an email blast can trip.
* [Multi-channel fallback and DLR](/concepts/multi-channel-dlr-fallback) —
  how the verify fan-out walks its channel chain and where receipts land.
* [Troubleshooting: conference lifecycle failures](/troubleshooting/conference-failures)
  — per-leg conference states, SIP codes, and the room-level event flow.
* [Error code reference](/reference/error-codes) — the generated
  definition of record for every code on this page.
