Error Codes
Error response format and troubleshooting for common error codes
Error response format
Errors return a non-2xx status with a JSON body:
{
"error": {
"message": "no available channel (distributor) (request id: ...)",
"type": "focal_api_error",
"code": "insufficient_quota"
}
}When troubleshooting, record the HTTP status, error.code, and the request id from the response.
Common error codes
| HTTP | code | Meaning | What to do |
|---|---|---|---|
| 400 | invalid_request_error | Missing/illegal parameters (e.g. duration out of range, wrong model name) | Check parameters against the API reference |
| 401 | invalid_api_key | Key missing, invalid or deleted | Verify the Authorization header and token status |
| 402 | insufficient_quota | Insufficient balance (including pre-charge cap) | Top up and retry; check token quota limits |
| 403 | permission_denied | No access to the model/feature | Confirm group and token model scope |
| 429 | rate_limit_exceeded | Rate limited | Reduce concurrency; retry with exponential backoff |
| 500 | internal_error | Server error | Contact the operator with the request id |
| 501 | endpoint_unavailable | Endpoint not implemented/open (e.g. Files, Fine-tunes) | Use an available endpoint instead |
| 502/503 | upstream_error | Upstream model service failure | Retry later; report persistent failures |
| 503 | capacity_exhausted | Creative capacity is full (queue admission limit reached) | The response carries Retry-After (usually 10 seconds); retry the same request with unchanged parameters — no need to switch models |
Async task errors
A failed video task is not an HTTP error — the task status becomes failed, details live in the task's error field, and the charge is refunded automatically. error.code TaskExpired means the task exceeded its execution deadline (including tasks whose submission state stayed unknown past the 10-minute reconciliation window); those are refunded as well.
When cancelling a queued task, 409 task_already_running / task_already_finished are normal contract responses: the first means generation already started and cannot be stopped, the second means the task already finished.
Troubleshooting checklist
- What are the HTTP status and
error.code? - Does the same key work in the console Playground? (Separates config issues from code issues)
- Does the model name match
GET /v1/modelsexactly? - For streaming, are SSE frames handled correctly?