> ## 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: MEDIA_UPLOAD_FAILED

> Diagnose the MEDIA_UPLOAD_FAILED (502) code on the three surfaces where it appears — WhatsApp media send/retrieve, the generic file-upload API, and compliance document upload — decode the stage the message names, and decide between retry and escalation.

# Troubleshooting: MEDIA\_UPLOAD\_FAILED

`MEDIA_UPLOAD_FAILED` is the code returned when a media upload or
download fails at the storage or provider hop. It shows up on three
surfaces: sending or retrieving WhatsApp media, uploading a file
through the file-upload API, and uploading a compliance document
(business registration, KYC, 10DLC evidence). The message is the
diagnosis surface: it names the stage that failed. Match the stage
below, then follow the fix for that stage.

## 1. Decode the stage in the message

The error message always includes a stage phrase. Start there — the
message tells you which of the three surfaces exploded and at which
step.

| Message (verbatim excerpt)                                                         | Surface                   | Stage              | Reads as                                                                                                  |
| ---------------------------------------------------------------------------------- | ------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------- |
| `Failed to resolve WhatsApp media: ...`                                            | WhatsApp                  | resolve            | Meta did not return a download URL for the media id — usually an expired media id or a failed Graph call. |
| `WhatsApp media response missing a valid CDN url`                                  | WhatsApp                  | resolve            | Meta returned a body that did not pass shape validation — the download URL was missing.                   |
| `Failed to download WhatsApp media from CDN`                                       | WhatsApp                  | download           | The platform resolved a URL but the CDN fetch itself failed.                                              |
| `WhatsApp media exceeds the 110 MB cap (declared / Content-Length / streamed ...)` | WhatsApp                  | size cap           | The media object is over the platform's 110 MB cap; see the size-cap section.                             |
| `File storage service temporarily unavailable (token refresh failed)`              | File upload               | GCS write          | The storage write hit a workload-identity token hiccup — a transient fault; safe to retry.                |
| `GCS bucket '...' not found ...`                                                   | Compliance or file upload | bucket probe       | The storage bucket does not exist — a deployment-config fault, not a retry problem.                       |
| `GCS permission denied ...`                                                        | Compliance or file upload | bucket probe/write | The API service account is missing write access to the bucket — an IAM/config fault.                      |
| `Document encryption failed: DEVOTEL_ENCRYPTION_KEY is not configured ...`         | Compliance                | encrypt            | The platform cannot encrypt the document before storing it — a pod-config fault.                          |
| `Compliance documents table not found in schema '...'`                             | Compliance                | DB insert          | The file reached storage but the tenant metadata table was missing.                                       |
| `Failed to store document in GCS: ...`                                             | Compliance                | upload             | A storage write failure that did not match the known config faults above.                                 |

## 2. WhatsApp media — resolve and download failures

WhatsApp media moves in two hops:

1. **Resolve** — the platform calls Meta's Graph API to turn a media id
   into a temporary CDN URL.
2. **Download** — the platform fetches the bytes from that URL.

A failure on the **resolve** hop means Meta did not hand back a URL.
The most common cause is a media id older than roughly a month — Meta
CDN URLs expire, so re-fetching long-past media fails deterministically.
A resolve failure can also be an upstream Graph error (an expired Meta
access token, a revoked WhatsApp connection). Retry is useful only for
a transient Graph blip; for an expired media id it resolves the same
way every time.

A failure on the **download** hop means the URL resolved but the CDN
fetch failed (a Meta-side blip). That class is retryable — a bounded
retry against Meta is reasonable.

If you are sending media **outbound** to WhatsApp and Meta rejects the
upload with its own media error (Meta error `131053` — size or MIME
problem), the code is `WHATSAPP_MEDIA_UPLOAD_FAILED`, not
`MEDIA_UPLOAD_FAILED` — check the exact code in the error payload before
following this page.

## 3. The 110 MB size cap on WhatsApp media

WhatsApp's documented ceilings are approximately: audio 16 MB, video
16 MB, voice 16 MB, image 5 MB, document 100 MB, sticker 100 KB. The
platform enforces a single upper bound of 110 MB across all media types
so a mis-classified or oversized payload cannot exhaust API memory.

When the message says the media exceeds the 110 MB cap, the fix is on
the sender side: compress or split the media below the cap, or send a
link instead of the binary. Meta's own ceiling may be lower than
110 MB for non-document types — with attachments above \~16 MB, prefer
sending the file as a WhatsApp `document`.

## 4. Generic file upload — storage faults

If you see this code from the file-upload API, the pipeline is writing
the object to the platform's storage bucket.

* **`token refresh failed`** — a transient workload-identity hiccup on
  the storage hop. It is safe to retry after a few seconds.
* **`bucket '...' not found` or `permission denied`** — a persistent
  storage-configuration fault; a retry fails the same way. This is the
  platform-side case that needs support (see below).

## 5. Compliance documents — the upload pipeline

Compliance document upload runs four steps in order: encrypt the file,
probe the storage bucket, write the object, then record metadata in the
tenant's schema. The message names which step broke:

* **encrypt** — `DEVOTEL_ENCRYPTION_KEY` is missing on the platform pod
  (a platform-side config fault) or the buffer failed encryption.
* **bucket probe / write** — the bucket is missing (platform config)
  or the API service account lacks write access (platform IAM). Both
  are platform-side; retrying does not help.
* **DB insert** — the file reached storage but the compliance
  documents table was missing from the tenant's schema, so the upload
  reports failure even though the file landed. Support can clear the
  orphaned file and finish tenant provisioning.

For the platform-side stages, the only customer-side check worth doing
is confirming the upload is well-formed (a readable file, a supported
MIME type, and a size under the upload cap you set) — then escalate if
the stage points decode to a platform fault.

## 6. Retry or escalate

* **Retry when the failure is transient** — a Meta Graph or CDN blip on
  the WhatsApp path, or a `token refresh failed` on the file-upload
  path. The platform already retries within the hop; a single manual
  retry after a short wait usually succeeds.
* **Do not retry when the gate is deterministic** — the 110 MB cap,
  an expired WhatsApp media id, or a message that names a bucket,
  IAM, encryption key, or missing-table stage. Fix the input or
  escalate.

## 7. What to give support

Escalate when the stage decodes to a platform-side fault (storage
bucket/IAM/encryption, or a missing compliance table) or when a
retryable class keeps failing. Include:

* The full error `message` — that string is the diagnosis.
* The document id, file name, file size, and MIME type.
* The tenant id (Settings → Organization).
* For WhatsApp: the media id and whether the failure is inbound
  (retrieving received media) or a new outbound attempt.

## See also

* [Error codes](/reference/error-codes) — the `MEDIA_UPLOAD_FAILED`
  and `WHATSAPP_MEDIA_UPLOAD_FAILED` table entries.
* [Compliance document error codes](/compliance/troubleshooting-compliance-error-codes)
  — the compliance-side bucket/IAM/encryption error catalogue.
* [WhatsApp connection and session errors](/troubleshooting/whatsapp-connection)
  — the channel-connection gates that also block outbound media sends.
