Skip to content

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

StatusTypical causeRetryableWhat to do
401Missing, truncated, disabled or expired keyNoCopy the key again from API Keys in the console, or create a new one
402Balance, key, member or department quota exhausted; video submission not covered by the balance reservationAfter topping upCheck what the key can still spend with GET /v1/usage, then top up or raise the quota; do not retry in a loop
403Account or member disabled, key or member not allowed on this group, or a capability not enabledNoContact your administrator, or use a key from a group that supports the call
404The model is not in this key's group, the path does not belong to it, or the group is offlineNoCall 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
413Request body over 60 MBNoCompress the media, or pass a URL where the model supports it
429Account or key concurrency cap reached, or the service is busy right nowYesRetry after Retry-After and lower your concurrency
499Console usage records only: the client disconnected first and never receives it—Stream long outputs and raise the client read timeout
502 / 503The service is temporarily unavailable; automatic retries did not succeedYesBack off and retry, or switch to another model in the same family
504The request timed outYesBack 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                                            Yes

Retry 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_id and start a new conversation.
  • 429 carries retry hints: Retry-After (seconds) and Retry-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: error

Handle 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                                            resubmit

When reporting a problem

  • The x-request-id response 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