---
title: "Handle errors, timeouts and retries"
canonical_url: https://docs.zvid.io/docs/operations/errors-and-retries/
source: docs/operations/errors-and-retries.md
content_revision: 6338386a1dd87e4a
---

# Handle errors, timeouts and retries

Read the HTTP status and structured error body together. Preserve the operation, job ID when available, `error`, `message` and validation details. Keep API keys, webhook secrets and sensitive variable data out of logs.

## Choose the correct recovery

| Status or symptom | Typical cause | Recovery |
| --- | --- | --- |
| 400 | Invalid fields, mutually exclusive inputs, unresolved variables, plan limits or unsupported options | Correct the request using `details`; validate it again |
| 401 | Missing, invalid or revoked credentials | Replace or correct authentication; do not repeatedly retry the same key |
| 402 | Insufficient available render credits | Inspect required/available credits and account balance before resubmitting |
| 403 | Account permission or access restriction | Verify the account and capability allowed for that route |
| 404 | Missing resource or resource not owned by this account | Verify ID and account; do not assume a job belongs to another user |
| 409 | A state conflict, such as deleting an active job | Re-read the resource and follow the endpoint's lifecycle rules |
| 413 | Request or upload exceeds a size limit | Reduce or split the input within documented limits |
| 429 | Hourly rate or concurrent-job capacity, including capacity needed by a bulk request | Read `current`, `limit`, `retryAfter` where supplied and honor `Retry-After` |
| 502, 503, 504 or network timeout | Temporary service/network problem, maintenance, or an uncertain response | Retry safe reads with bounded backoff; reconcile state-changing requests first |
| `state: "failed"` | An accepted render failed | Inspect `failedReason`, correct the cause and deliberately submit a new job if needed |

Exceeding the bulk request's item-count cap is a `400` validation error; it is different from a `429` capacity limit. Not every endpoint returns every status or field. The endpoint reference documents its contract. Errors can occur before the controller, so a failed response is not always shaped like a successful response with one extra property.

## Avoid duplicate paid renders

A connection can fail after a render was accepted but before your client received its job ID. Blindly retrying the POST can create another paid render. The presence of a client-supplied job identifier does not establish a general idempotency guarantee for all routes.

Store successful submission responses immediately. If the outcome is uncertain, inspect recent jobs and the dashboard, correlate with your business record and any returned job identifier, then decide whether to submit again. Do not turn a polling timeout into a new render submission.

SDKs and HTTP libraries can retry automatically, including POST requests. Review those defaults and disable request retries for paid submissions when your application cannot reconcile duplicates. The [Node.js example](https://docs.zvid.io/examples/render-once.mjs) submits once and retries only status reads.

## Bounded retries for reads

Use exponential backoff with jitter for temporary read failures. Respect a valid `Retry-After` value, whether it is a number of seconds or an HTTP date. Bound both total waiting time and per-request timeout, and stop when the caller cancels.

For `429` caused by a concurrent-job limit, allowing current jobs to finish may be necessary; rapid retries will not create capacity. For a validation error, retries with identical input will not fix the request.

## Diagnose media and layout separately

A structurally valid project can still encounter an inaccessible source URL, corrupt media or rendering failure. Check [media access](https://docs.zvid.io/docs/concepts/media-assets/), then isolate the failing element. Incorrect placement, clipping and timing often need a payload correction rather than a retry; use the [layout](https://docs.zvid.io/docs/concepts/layout/) and [timing](https://docs.zvid.io/docs/concepts/timing/) guides.

When asking for help at [https://zvid.io/contact](https://zvid.io/contact), include the job ID, approximate UTC time, route, HTTP status and a redacted minimal request. Never include the API key or webhook signing secret.
