Language
Inference Space Docs

Error Codes and Error Handling

Error response JSON structure, common error codes by HTTP status (authentication, parameters, model authorization, balance, rate limits, image-specific errors), and retry recommendations.

Every endpoint signals an error with a non-2xx status code plus a JSON error body. Use the HTTP status to decide between "fix the request" and "retry", then branch precisely on the machine code in the body.

Error Body Structure

Error details always live in the top-level error object:

{
  "error": {
    "message": "Human-readable error description",
    "type": "bad_request",
    "code": "optional_machine_code",
    "param": "image"
  }
}
FieldDescription
messageHuman-readable description; fine for developers, not recommended to show verbatim to end users
codeStable machine code — branch on it first when present
typeError category; on some endpoints the machine code appears only here
paramThe offending request field (only on some parameter errors)

Differences between endpoint families:

  • Chat endpoints (/v1/chat/completions, /v1/responses): gateway-side errors are identified by error.code and usually carry no type; rate-limit errors also include retry_after_seconds.
  • /v1/messages uses the Anthropic format: {"type": "error", "error": {"type": "invalid_request_error", "message": "..."}}, where error.type is an Anthropic value such as invalid_request_error / authentication_error / permission_error / rate_limit_error / api_error. There is no gateway machine code in this protocol, so handle errors by HTTP status (for example, insufficient balance is also 429).
  • Image, speech, OCR, and vision segmentation use error.type primarily; some errors also carry code.

Recommended parsing:

def error_code(body: dict) -> str | None:
    err = body.get("error")
    if isinstance(err, dict):
        return err.get("code") or err.get("type")
    return err if isinstance(err, str) else None

Quick Reference by Status

HTTPTypical machine codesMeaningWhat to do
400bad_request, invalid_request, invalid_request_body, model_requiredMissing / malformed parameter, or the body is not valid JSONFix the request; do not retry
400model_not_available_for_routingThe model name does not exist or is currently unavailableCheck the name against the model catalog
400model_retiredThe model has been retiredSwitch to another model
400wrong_endpoint_for_modelAn image / video model was sent to a chat endpointUse the matching endpoint
401missing_api_key, invalid_api_key, authentication_requiredKey missing, invalid, or (on chat endpoints) lacking the scopeSee Authentication and API Keys
402MISSING_MULTI_CURRENCY_PRICE, MODEL_PRICE_NOT_CONFIGURED (type is billing_error)The model has no price configured for your organization; the gateway rejects instead of serving it for freeContact support to complete pricing, then retry
403insufficient_scope, ip_not_allowedKey lacks the scope / source IP not on the allowlistSee Authentication and API Keys
403model_not_allowed_for_api_key, image_model_not_allowed, image_size_not_allowedOutside the key's model scope / image size tiersAdjust the key's restrictions or use another key
403model_not_authorized_for_orgThe model is not enabled for your organizationAsk your administrator to enable it
429rate_limit_exceeded (speech / OCR use rate_limit)Organization or key rate / quota exceededBack off per retry-after (image endpoints omit the header; use exponential backoff); see Rate Limits and Quotas
429BILLING_BLOCKEDInsufficient account balance or a budget cap reachedTop up or adjust the budget; plain retries will not succeed
429all_providers_rate_limitedThe model is at capacity right nowBack off per retry-after (30 seconds)
451content_policy_rejectedImage content failed the safety reviewChange the prompt / reference images
502routing_dispatch_failed, upstream_errorServer-side processing failedRetry a limited number of times with backoff
503all_candidates_exhausted, provider_rpm_unavailable, image_routing_unavailable, image_buffer_overloadService temporarily busy or unavailableRetry a limited number of times with backoff; honor retry-after when present
503handler_unhandled_exceptionInternal gateway exception (still returns JSON rather than dropping the connection)Retry a limited number of times
504upstream_timeoutProcessing timed outRetry later; for images, try a lower size tier

Insufficient Balance and Pricing Errors

Insufficient balance returns 429, not 402. Distinguish it from ordinary rate limiting by the machine code:

{
  "error": {
    "code": "BILLING_BLOCKED",
    "message": "账户余额不足,请及时充值后重试",
    "type": "rate_limit_exceeded"
  }
}
  • Prepaid accounts are blocked from new requests once the balance (including vouchers) is ≤ 0; service resumes automatically once a top-up lands.
  • Reaching an organization or key daily / monthly budget, or a key's total spending cap, also returns BILLING_BLOCKED.
  • On chat endpoints the message for this error may just say "too many requests" — branch on code.

402 pricing not configured means the model has no valid price for your organization yet, so the gateway rejects the request instead of serving it at zero cost. Contact support; retrying does not help.

{
  "error": {
    "code": "MISSING_MULTI_CURRENCY_PRICE",
    "message": "模型计价信息未确认,请联系客服处理",
    "type": "billing_error"
  }
}

Common Image Errors

HTTPBody highlightsScenario
400type: bad_request, param: image, message: 参考图片数量超出上限(最多 N 张) ("too many reference images, max N")Too many reference images: Gemini-family image models (such as Nano Banana) accept at most 14, other models (such as gpt-image-2) at most 16
400type: bad_request, param: imageAn image edit supplied no reference image
400type: bad_request, message: prompt is requiredMissing prompt
400code: invalid_image, param: imageA reference image cannot be decoded (not an image, truncated, or not the declared format; PNG / JPEG / WebP are supported)
400code: image_prompt_rejected, param: promptThe prompt's length or format does not meet the model's requirements
403code: model_not_authorized_for_orgThe image model is not enabled for your organization
403type: image_routing_requiredNo capacity currently matches this request's parameters (size tier, quality, etc.), or routing does not match
429type: rate_limit_exceededOrganization image RPM exceeded (default 500 requests/minute unless configured otherwise); or code: BILLING_BLOCKED for insufficient balance
451type: content_policy_rejectedGenerated content failed the safety review
503type: image_buffer_overload, header retry-after: 5Momentary overload
504type: upstream_timeoutImage generation timed out
{
  "error": {
    "message": "参考图片数量超出上限(最多 16 张)",
    "type": "bad_request",
    "param": "image"
  }
}

A reduced image count is not an error: if you request n images (max 4) and fewer can be delivered, the endpoint still returns 200 with the response header x-image-count-degraded: delivered/requested (e.g. 1/4). Always count images by data.length.

Retry Recommendations

Long requests such as image generation / editing and long-context chat can take a while. Set your client timeout to ≥ 600 seconds, or the client may disconnect while the server is still working.

  • 400 / 401 / 402 / 403 / 451: request-side problems; retrying is pointless — fix and resend.
  • 429: check code first — BILLING_BLOCKED needs a top-up; otherwise read the retry-after header and back off before retrying (use exponential backoff when it is absent). Never retry in a tight loop.
  • 502 / 503 / 504: retry a limited number of times (≤ 3 recommended, exponential backoff), waiting for retry-after when present.
  • When reporting an issue, keep the request ID from the response (such as the x-gateway-request-id header, if present) and the time it happened so support can locate it.

On this page