Error Codes and Troubleshooting
Applicable role: Developer Last updated: 2026-08-06
This page lists common error responses along with recommended inspection steps, retry logic, and timeout guidelines.
1. Error Code Quick Reference
| HTTP Code | Error Code | Meaning | What You Should Do |
|---|---|---|---|
| 400 | invalid_request_error |
Invalid request parameters | Check your request body format and parameters |
| 401 | invalid_api_key / authentication_error |
API Key is invalid or missing | Check the Authorization: Bearer header; the OpenAI-compatible endpoint returns invalid_api_key, while the Messages-compatible endpoint returns authentication_error |
| 403 | insufficient_balance |
Organization balance depleted | Contact your organization to top up |
| 403 | USAGE_LIMIT_EXCEEDED |
Member user quota capped | Contact the admin user to raise the quota pool limit |
| 403 | region_not_admitted |
Your account does not meet the target group's region or authorization policy | Switch to an authorized model group, or contact the platform to verify your organization's authorization. Note: the OpenAI-compatible endpoint and Messages-compatible endpoint return this error code with different response body structures; your parser should handle both formats |
| 403 | API_KEY_EXPIRED |
API Key has expired | Contact the admin user to reissue the Key |
| 403 | fingerprint_routing_disabled |
Group identifier routing is not enabled | Contact the admin user to enable group identifier routing in organization settings |
| 403 | group_not_allowed |
Target group is not in the allowed scope | Verify group authorization, or switch to an authorized group |
| 403 | Unbound group / default routing misconfigured | The Key is not bound to any group, or the bound group does not match the target model and the default configuration has become invalid | Bind a valid group to the Key first; update the default model configuration if necessary |
| 429 | API_KEY_RATE_{5H,1D,7D}_EXCEEDED |
Key rate limit exhausted (5h / 1d / 7d window) | Wait for the rate-limit window to reset or raise the limit |
| 429 | API_KEY_QUOTA_EXHAUSTED / concurrency-related |
Key quota exhausted or concurrency exceeded | Adjust Key quota / reduce concurrency / contact the admin user. Note: the OpenAI-compatible endpoint returns a top-level code field, while the Messages-compatible endpoint returns a nested error.type structure |
| 502 | upstream_error |
Model provider returned 5xx, uniformly mapped | Retry after a short delay |
| 500 | internal_server_error |
Platform internal failure | Contact technical support |
The specific
codefor 403 and 429 may vary depending on the trigger condition. Your client should classify by HTTP status code first, then read thecodefrom the response body — do not rely on a single error string.API_KEY_RATE_5H_EXCEEDED,API_KEY_RATE_1D_EXCEEDED, andAPI_KEY_RATE_7D_EXCEEDEDcan be used to identify the corresponding rate-limit window.
About 429 subcategories: Rate-limit exhaustion returns
API_KEY_RATE_5H_EXCEEDED/API_KEY_RATE_1D_EXCEEDED/API_KEY_RATE_7D_EXCEEDEDby time window — wait for the window to reset. Quota exhaustion or concurrency overload requires adjusting quota or reducing concurrency.
Upstream 5xx responses are mapped to 502; platform failures return 500. A 403 typically requires adjusting balance, permissions, or quota; a 429 typically requires waiting for the window to reset, reducing request frequency, or adjusting quota.
Three Subtypes of 403 (Completely Different Troubleshooting Paths)
Although they all return 403, the required actions differ significantly. Check the code before taking action:
| Subtype | Typical Code | Root Cause | Correct Action | Common Misdiagnosis |
|---|---|---|---|---|
| Region or authorization policy mismatch | region_not_admitted |
Account does not meet the target group's policy | Switch to an authorized model group, or contact the platform to verify authorization | Repeatedly retrying the same unavailable group |
| Group not authorized | Authorization-related | The group is not granted to this organization / member user | Ask the admin user or platform to grant group access | Assuming insufficient balance |
| Insufficient balance or quota | Balance/quota-related | Organization balance depleted, or member user pay-as-you-go quota capped | Top up / raise quota | Assuming the entire account is suspended — Keys bound to subscription groups are unaffected |
Regarding the third subtype, there is a common pitfall: eligibility is determined per Key based on its bound group. When the organization balance reaches 0, subscription-based Keys continue to work normally — only pay-as-you-go Keys will receive 403. To check which Keys are currently usable, go to the "API Key" page in the console and look at the "Billing Source" column and the summary bar at the top; treat that page as the source of truth.
region_not_admitted indicates that your account does not meet the target group's region or authorization policy. Your client can display a sanitized message to the user and guide them to switch to an authorized model group. For more context, see Model Availability and Group Authorization.
Calls with a group identifier are routed to the specified group. If the group is not authorized or the account is ineligible, the platform returns an error — it does not automatically switch or fall back. Plain model names require the Key to have a bound group; default model configuration is consulted only when the bound group does not contain the target model. See Call Guide and Dual Routing for the full mechanism.
2. Error Response Body Formats
The platform's error response bodies come in multiple formats; your error parser should handle all of them.
Format A: Request Validation (Nested error Object)
400 parameter errors, 401 authentication failures, and 502 provider faults are returned by the platform with error details inside an error object. Note: Whether the outermost type: "error" wrapper is present depends on whether the Messages-compatible endpoint or the OpenAI-compatible endpoint was hit — even within the same endpoint, different groups may produce different outer structures:
// Messages-compatible endpoint
{
"type": "error",
"error": { "type": "upstream_error", "message": "Upstream service temporarily unavailable" }
}
// OpenAI-compatible endpoint — no outermost type
{
"error": { "type": "invalid_request_error", "message": "..." }
}Parsing recommendation: Always read
error.typeanderror.message; do not rely on whether the outermosttypefield exists. The fields inside theerrorobject are consistent across both endpoint types.
Common error.type values:
error.type |
Scenario |
|---|---|
invalid_request_error |
400 parameter error |
authentication_error |
401 authentication failure |
not_found_error |
404 model or endpoint not found |
rate_limit_error |
429 rate limit / quota exceeded |
permission_error |
403 insufficient permissions / region restriction |
upstream_error |
502 model provider fault |
Format B: Authentication / Billing / Rate Limit (Top-Level code / message)
The most common 403 balance/quota and 429 rate/quota business errors use a different structure, with the error code in a top-level code field (string) and no outer type/error wrapper:
{
"code": "API_KEY_RATE_5H_EXCEEDED",
"message": "rate limit exceeded"
}Format C: 500 Platform Internal Failure
{
"code": 500,
"reason": "internal_server_error",
"message": "internal error"
}Your error parser should handle both top-level
codeand nestederror.type. The 500 response may also contain an integercodeand areasonfield; your client should preserve unknown fields to avoid parse failures when new error types are introduced.
3. Determining "Whose Problem Is It"
After receiving an error, use the HTTP status code to determine the direction:
- 4xx — The request itself is problematic (parameter error, authentication failure, insufficient balance, rate limit exceeded, default routing misconfigured). Check the request content. If you included a group identifier but received
fingerprint_routing_disabledorgroup_not_allowed(group identifier routing must be enabled), the group is not in the allowed scope or is currently unavailable (no automatic fallback) — switch to an available group or contact the platform. If you are using default routing and get an error, the group configured for default routing may have become invalid — contact the admin user to update the configuration. - 500 — Platform internal failure; contact customer support.
- 502 — Model provider failure (provider 5xx responses are uniformly mapped to 502); retry after a short delay.
When unsure whether the fault lies with the platform or the model provider, check the error code first: 502 points to the model provider; 500 points to the platform itself.
4. Recommended Retry Strategy
import time
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://<your-api-endpoint>")
def chat_with_retry(messages, max_retries=3):
for attempt in range(max_retries):
try:
return client.chat.completions.create(
model="deepseek-v4-flash",
messages=messages,
timeout=60
)
except Exception as e:
status = getattr(e, "status_code", None)
# 4xx client errors are not retried (retrying won't help)
if status and 400 <= status < 500 and status != 429:
raise
# 429/502/500 exponential backoff retry
if attempt < max_retries - 1:
wait = 2 ** attempt # 1s, 2s, 4s
time.sleep(wait)
else:
raisePrinciples:
- Do not retry 4xx (except 429) — parameter errors, authentication failures, insufficient balance, expired Keys, and unavailable groups with group identifiers are not transient; retry is pointless. Handle each error type accordingly (fix parameters, contact the admin user to top up or reissue the Key, switch to an available group, etc.)
- Retry only 429 / 502 / 500 with exponential backoff (1s -> 2s -> 4s) to avoid flooding
- Set a timeout — 60s is recommended to prevent requests from hanging indefinitely
- Limit maximum retries — typically 3, to avoid infinite retry loops
5. Special Handling for Streaming (SSE) Scenarios
When an error occurs mid-stream, you will first receive partial content chunks, followed by an error event:
data: {"choices":[{"delta":{"content":"partial content"}}]}
data: {"type":"error","error":{"type":"upstream_error","message":"..."}}The connection then closes. Recommendations:
- Detect error events separately in your SSE parsing logic — do not treat them as normal content
- The "partial content" already rendered on the client side requires a business-level decision on how to handle it (clear it / mark as interrupted / allow regeneration)
- This is the most common pitfall in streaming calls; consider wrapping a unified streaming error handler
6. What to Provide When Contacting Technical Support
When reaching out to platform support, include the following information to speed up diagnosis:
- The timestamp of the error (accurate to the minute, with timezone)
- The model call name used (model name or with group identifier) and the endpoint
- The HTTP status code and full error response body
- Whether streaming was used (
stream) - Approximate request frequency (helps determine if rate limiting is involved)