Error codes and retries
Read HopBase error responses, including streaming failures, and decide when to retry.
To look up a specific symptom, use Troubleshooting. This page is the full reference. For concurrency caps, timeouts and billing, see Concurrency, timeouts, and billing.
Error response shape
OpenAI protocol (/v1/chat/completions, /v1/responses, /v1/images/*, /v1/video/*):
{
"error": {
"message": "…",
"type": "invalid_request_error",
"code": "insufficient_quota"
}
}Anthropic protocol (/v1/messages):
{
"type": "error",
"error": { "type": "invalid_request_error", "message": "…" }
}The Anthropic shape has no code. Key-validation errors (401, quota 402, account 403) always use the OpenAI shape, even on /v1/messages. Message language follows the Accept-Language request header and defaults to English. In code, branch on the HTTP status and code, never on the message text.
Status codes
| Status | Typical cause | Retryable | What to do |
|---|---|---|---|
| 401 | Missing, truncated, disabled or expired key | No | Copy the key again from API Keys in the console, or create a new one |
| 402 | Balance, key, member or department quota exhausted; video submission not covered by the balance reservation | After topping up | Check what the key can still spend with GET /v1/usage, then top up or raise the quota; do not retry in a loop |
| 403 | Account or member disabled, key or member not allowed on this group, or a capability not enabled | No | Contact your administrator, or use a key from a group that supports the call |
| 404 | The model is not in this key's group, the path does not belong to it, or the group is offline | No | Call GET /v1/models with this key to confirm the ID; for paths see Base URL and protocols; retired IDs and their replacements are in the model changelog |
| 413 | Request body over 60 MB | No | Compress the media, or pass a URL where the model supports it |
| 429 | Account or key concurrency cap reached, or the service is busy right now | Yes | Retry after Retry-After and lower your concurrency |
| 499 | Console usage records only: the client disconnected first and never receives it | — | Stream long outputs and raise the client read timeout |
| 502 / 503 | The service is temporarily unavailable; automatic retries did not succeed | Yes | Back off and retry, or switch to another model in the same family |
| 504 | The request timed out | Yes | Back off and retry; use streaming or async endpoints for long jobs |
Error codes
# The code field of OpenAI-shaped bodies. A 400 raised by the model itself may carry that model's own code.
Status code Meaning Retry
401 missing_api_key No key sent No
invalid_api_key Key invalid or deleted No
api_key_expired Key expired No
402 insufficient_quota Balance, key, member or department quota used up After top-up
insufficient_balance Video: balance can't cover in-flight + this estimate After tasks end / top-up
403 account_disabled Account disabled No
member_disabled Member account disabled No
member_group_forbidden Member may not use this key's group No
api_key_misconfigured Key not bound to any group No
image_generation_disabled Image generation not enabled for the group No
middleware_denied Rejected by gateway policy No
404 model_not_found Group does not support this model No
model_not_served Group does not provide this model No
group_offline Group taken offline No
route_not_found Path not supported for this key No
400 invalid_request Unreadable / non-object body, missing model, empty messages No
413 request_too_large Body over 60 MB No
429 user_concurrency_limit Account concurrency cap (Retry-After: 1) Yes
apikey_concurrency_limit Key concurrency cap (Retry-After: 1) Yes
all_routes_rate_limited Service busy Yes
upstream_rate_limit Service busy Yes
502 upstream_error Service temporarily unavailable Yes
503 no_available_route Service busy Yes
no_available_account Service busy (see the session exception below) Yes*
all_routes_failed Service temporarily unavailable Yes
plugin_unavailable Service temporarily unavailable Yes
service_unavailable Authentication service briefly unavailable Yes
504 upstream_timeout Timed out YesRetry rules
- Never retry unchanged: 400, 402, 403, 404, 413, 422. Fix the request, the configuration or the balance first. 404 is final: temporary unavailability returns 429 / 5xx, never 404.
- Retry with backoff: 429, 502, 503, 504, and interrupted streams. Suggested delays are 2s, 5s and 15s, up to three attempts. Except the 503 saying the stateful session "can no longer be resumed": drop
previous_response_idand start a new conversation. - 429 carries retry hints:
Retry-After(seconds) andRetry-After-Ms(milliseconds). Honour them when present. - Never resubmit an accepted async job: each resubmission creates another separately billed task — poll instead.
Streaming failures
Once a streaming response starts, the HTTP status is already 200 and never changes. Later failures arrive as events:
Chat Completions data: {"error": {…}} (no event: line)
Responses event: response.failed (response.error.code: rate_limit_exceeded / server_error / invalid_prompt)
Anthropic event: errorHandle error events inside your read loop. Partial output cannot be resumed — reissue the whole request.
Async task failures
A rejected submission returns a normal 4xx and creates no task. A task that fails after acceptance still polls as 200 with status: "failed" and the reason in error.message (image tasks: an error string) — no code (Kling and Midjourney tasks do return a stable error.code, such as input_sensitive, invalid_request or generation_failed), and it is not billed. Never resubmit moderation or parameter failures unchanged. Console Usage shows the category and next step:
Moderation input_sensitive, safety_rejected … revise prompt / media
Parameters prompt_required, upstream_invalid_request, reference_* … fix parameters
Timeout per family, see Concurrency, timeouts, and billing resubmit
Interrupted task_interrupted resubmitWhen reporting a problem
- The
x-request-idresponse header — every response carries one and it identifies that exact request - The time (with timezone) and the model ID
- The full error text and HTTP status
The console hides the original text of service-side failures, so we trace by x-request-id. Contact us with those and we can trace the request directly.
Next steps
- Troubleshooting: look up an error message
- Concurrency, timeouts, and billing: concurrency caps, timeouts, and billing rules
- Account and catalog API: check the balance, usage, and model catalog over the API