TROUBLESHOOTING · ERROR FAQ
Veo 3 API Error Handling: Every Error Code & What To Do
Video generation over an API fails in two phases, and most "Veo error" confusion comes from treating them as one. Phase one: the submit call itself is rejected — auth, parameters, quota, balance. Phase two: the submit succeeds, then the task fails while you poll — safety review, upstream capacity, timeout. This page gives a triage table for both phases, thresholds for deciding a task is hung, a retry strategy built on idempotency keys, and how a unified gateway normalizes errors so one handler covers every Veo 3.1 tier. Adjacent reads: polling done right and the Kling error guide.
Two failure phases: submit vs poll
Submit-phase errors are synchronous and cheap: you get an HTTP status and a code immediately, nothing was generated, and nothing is owed. Poll-phase errors are asynchronous: the task ID exists, credits may have been provisionally held, and the failure arrives as a terminal task state. Handling requirements differ — phase one is a request problem, phase two is a workflow problem.
Triage table
- 401 / 403: key missing, wrong, or lacking scope. Fix credentials; never retry with the same key blindly.
- 422 / 400: parameter problem — model name typo, unsupported resolution/duration combination, malformed prompt field. Read the body; correct and resubmit.
- 429: rate limit. Retryable with exponential backoff; check headers for the reset window.
- 402 / insufficient credits: billing. Top up or switch key; retries make it worse.
- 5xx at submit: upstream capacity. Retryable with backoff and jitter.
- Poll-phase FAILURE: usually content review or upstream drop; check the task's error code — filter hits are not retryable, capacity drops are.
- Stuck in queued/in_progress: not an error yet — see the threshold section.
Polling thresholds: when a task counts as hung
Set a maximum wall-clock budget per generation (a sensible default is 10 minutes for 8-second clips) and a maximum poll count, whichever hits first. On breach, mark the task timeout-suspect and query once more with a fresh request (cheap insurance against a connection-level false negative), then declare it hung and either resubmit or surface it. Never loop without both limits: a task stuck in RUNNING is otherwise indistinguishable from a working one.
Retry strategy: idempotency keys + exponential backoff
Retries without idempotency create duplicate billable generations. Attach an idempotency key (any stable string derived from your request) so a retry of the same submit de-duplicates server-side. Backoff schedule: 1s, 2s, 4s, capped at ~30s with jitter, retryable errors only — everything else routes to alerting. The retryable flag in the error body is the gate; retrying a 422 just burns your rate budget.
Unified gateway: one error contract across channels
Behind a gateway, the same model served over multiple upstream channels returns one normalized error shape — {code, retryable, action} — regardless of which channel actually failed, and failed tasks are not charged. One handler covers Veo 3.1 Fast and Quality tiers, and the same handler covers every other model in the catalog. Start from the quickstart for working submit/poll code in curl, Python, and JS.