The Qwen API has two common calling paths: the native DashScope interface on Alibaba Cloud Model Studio, and the OpenAI-compatible interface. Their error structures are not identical, but the troubleshooting order is the same: check the HTTP status code first, then read the code and message in the response body, then find the request_id, reproduce with a minimal request, and only then change parameters or switch models.
This article breaks down 401, 404, 429, 400, 5xx, and timeouts, with an error-code reference, logging fields, retry code, and a checklist to complete before contacting support. Models, quotas, and billing are governed by the official documentation and the model pricing page.
Note: Qwen, Tongyi Qianwen, Alibaba Cloud, Model Studio, and DashScope are trademarks of Alibaba Group and its affiliates. This article is a technical troubleshooting discussion only and implies no affiliation, agency, or partnership with those companies. Error codes, rate-limit policies, and API behavior may change between versions; the official documentation and actual responses are authoritative.
1. First distinguish the interface mode and error structure
The native DashScope interface usually returns code, message, and request_id at the top level of the response. The OpenAI-compatible interface follows OpenAI conventions, with an error body shaped like {"error": {"message": "...", "type": "...", "code": "..."}}. In compatible mode, request_id may appear in a response header or in the body; use the field names actually returned.
Do not parse only one structure in production code. Log the complete response body verbatim first, then read the code from error.code and fall back to the top-level code. That way, switching interface modes does not require rewriting your error handling.
2. 401: authentication failure, check the region first
A 401 means identity verification failed and is usually unrelated to model capability or balance. Three common Model Studio errors are:
InvalidApiKeyorinvalid_api_key: the key is wrong, was copied incompletely, or the base URL does not match the key's region.invalid access token or token expired: the token has expired, or a plan-specific endpoint was used with an ordinary key.- A workspace permission error: the WorkspaceId is invalid, or the account does not belong to that workspace.
Qwen API keys are bound to a region, and Beijing and Singapore keys cannot be mixed. This is the easiest point to miss: the code is unchanged, only the base URL was swapped, and 401s reproduce consistently.
Troubleshoot in this order:
- Confirm the request header is
Authorization: Bearer <key>, with one space after the colon. - Print the prefix of the environment variable and confirm it is not empty, stale, or padded with a newline.
- Check that the base URL matches the region that owns the key.
- Confirm the key type matches the endpoint: pay-as-you-go, coding plans, and token packages use different addresses.
- Try a new key with a minimal request to separate key problems from proxy or gateway problems.
3. 404 and 400: model names, activation status, and context
A 404 is usually not a service outage but a problem with the model name or availability. For ModelNotFound or model_not_found, check three things first: whether the model name is misspelled, whether the model has been activated, and whether it is available in the current region. model_not_supported means the model does not support OpenAI-compatible mode, so you need a different interface or model.
The causes of 400 are more varied. InvalidParameter means a parameter is out of range, such as temperature or top_p exceeding its bounds; InvalidParameter.NotSupportEnableThinking means the model does not support thinking-mode parameters. Context overflow usually returns Range of input length should be [1, xxx], with the underlying code InternalError.Algo.InvalidParameter, or the total message length may exceed the model limit. Handle it by trimming history, summarizing in chunks, or moving to a long-context model, not by retrying repeatedly.
4. 429: separate four rate-limit types and two quota states
429 is the error most often mishandled. A Model Studio 429 covers at least the following categories; the table also lists arrears and unactivated-service errors that are easily confused with rate limiting:
| HTTP | Error code | Meaning | Suitable for retry |
|---|---|---|---|
| 429 | Throttling.RateQuota, LimitRequests |
Requests per minute (RPM) exceeded | Yes, retry after backoff |
| 429 | Throttling.AllocationQuota, insufficient_quota |
Tokens per minute (TPM) exceeded | Yes, back off and reduce input |
| 429 | Throttling.BurstRate |
Short-term traffic spike triggers protection | Yes, smooth the send rate |
| 429 | Throttling.Concurrency |
Too many concurrent requests | Yes, reduce concurrency |
| 429 | AllocationQuota.FreeTierOnly |
Free quota exhausted with free-tier-only enabled | No, top up or disable the switch |
| 429 | BudgetLimitExceeded |
Account budget exhausted | No, adjust the budget |
| 400 | Arrearage |
Account in arrears or in an abnormal state | No, restore the account first |
| 403 | AccessDenied.Unpurchased |
Service not activated | No, activate it first |
Rate limits are counted at the Alibaba Cloud primary account level. Calls from RAM sub-accounts, workspaces, and multiple keys are combined. So "one key per service" does not bypass the total quota; it only prevents services from crowding each other out. Limits usually recover within a minute, so do not retry aggressively while waiting.
5. Timeouts and 5xx: locate the stage in three parts
Timeouts need to be divided into three stages. A connection timeout usually means DNS, egress, or a proxy is unreachable. A slow first token is often upstream queuing or an overlong input. A read timeout may mean the output is too long or reasoning is taking a long time. The remedies differ, and simply raising the timeout value is not one of them.
Model Studio's RequestTimeOut indicates a request timeout, and the documented request limit is 300 seconds; GatewayTimeout.InputDownload relates to downloading an input file. The OpenAI-compatible interface may also return 503 when the engine is overloaded. When a streaming request is interrupted, there may be no error code; record the content received so far, the last chunk, and the finish reason before deciding whether the cause is network jitter, a proxy dropping the stream, or an upstream timeout.
6. request_id and logs: the evidence for troubleshooting
The official documentation states that a request_id is returned with the response, possibly in a header or in the body. In practice, log on two tracks: generate a client-side trace_id that spans all retries, and save the request identifier from the response headers and the request_id from the body verbatim. If these were not recorded, look in the console's model monitoring logs, provided inference logging was enabled.
Log at least: timestamp, trace_id, base URL, region, model name, HTTP status code, error code, error message, request_id, elapsed time, retry count, and whether the request was streamed. Record only the first few characters of a key or a hash; do not write user content and full responses to disk in bulk. When contacting support, one record with these fields is far more useful than "it errors occasionally."
7. Retries and backoff: example code
The code below disables automatic SDK retries, retries only recoverable 429s and 5xx responses, and prints the status code, error code, and request_id together. Arrears, exhausted free quota, and budget overruns are not retried.
import os
import random
import time
import uuid
import httpx
from openai import OpenAI, APIConnectionError, APIStatusError, APITimeoutError
client = OpenAI(
api_key=os.environ["DASHSCOPE_API_KEY"],
base_url=os.environ.get(
"DASHSCOPE_BASE_URL",
"https://dashscope.aliyuncs.com/compatible-mode/v1",
),
timeout=httpx.Timeout(connect=5.0, read=180.0, write=30.0, pool=10.0),
max_retries=0, # disable SDK retries; the logic below controls them
)
RETRYABLE_429 = {
"Throttling",
"Throttling.RateQuota",
"Throttling.AllocationQuota",
"Throttling.BurstRate",
"Throttling.Concurrency",
"LimitRequests",
"limit_requests",
"ResourceExhausted",
}
def unpack_error(exc: APIStatusError):
body = {}
try:
body = exc.response.json()
except Exception:
pass
err = body.get("error", body) if isinstance(body, dict) else {}
code = err.get("code") if isinstance(err, dict) else None
request_id = None
if isinstance(body, dict):
request_id = body.get("request_id")
request_id = (
request_id
or exc.response.headers.get("x-request-id")
or exc.response.headers.get("x-dashscope-request-id")
)
return code, request_id, exc.response.text[:500]
def ask(prompt: str, model: str, max_attempts: int = 4) -> str:
trace_id = uuid.uuid4().hex[:12]
for attempt in range(1, max_attempts + 1):
try:
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
)
return resp.choices[0].message.content
except APIStatusError as exc:
code, request_id, body = unpack_error(exc)
print(
f"trace={trace_id} attempt={attempt} "
f"http={exc.status_code} code={code} "
f"request_id={request_id} body={body}"
)
retryable = exc.status_code >= 500 or (
exc.status_code == 429 and code in RETRYABLE_429
)
if not retryable or attempt == max_attempts:
raise
except (APITimeoutError, APIConnectionError) as exc:
print(f"trace={trace_id} attempt={attempt} err={type(exc).__name__}")
if attempt == max_attempts:
raise
wait = min(2 ** (attempt - 1), 30) + random.uniform(0, 1)
time.sleep(wait)
raise RuntimeError("retry attempts exhausted")
Three additional rules: honor a server-provided Retry-After header first; control the retry budget globally so multiple services do not amplify traffic at the same time; and for requests with side effects, confirm whether the operation already executed before resending.
8. Concurrency governance: more effective than increasing retries
Rate-limit problems are usually solved at the entry point, not by retrying:
- Split keys by business function and set separate concurrency caps, so one batch job cannot take down an online service.
- Shard batch jobs and stagger their schedules to avoid on-the-hour traffic spikes.
- Use queues to absorb peaks, sending failed tasks to a delayed queue instead of retrying in place.
- Monitor the share of 429s and p95 latency; when they spike, reduce concurrency first.
- Prefer the Batch interface for offline jobs to avoid real-time rate limits.
- Prepare a backup model or entry point, and confirm parameter compatibility before switching.
Rate-limit thresholds are configured per model and account. Topping up does not automatically raise RPM or TPM. If you need a higher quota, go through a commercial request rather than copying someone else's numbers.
9. Checklist before contacting support
- Time of occurrence, time zone, and whether failures occurred in a burst.
- Base URL, region, endpoint path, model name, and request method.
- HTTP status code, error code, and the full error message.
request_id; if unavailable, provide your owntrace_id.- A minimal reproducible curl request with the key redacted.
- Whether the request was streamed, used long context, or followed a recent configuration change.
- Scope of impact: one key, one workspace, or all services.
10. FAQ
1. Is a 429 always rate limiting?
No. A 429 can also mean the free quota is exhausted or the budget limit was reached. Arrears may return a 400 Arrearage, and an unactivated service may return 403. Read the error code first, then decide whether to back off, top up, or change configuration.
2. A 401 persists after changing the key. What now?
Focus on the region and key type. Qwen keys are bound to a region; a Beijing key with a Singapore endpoint returns 401, and a plan-specific endpoint with an ordinary key also fails. Then check the request header, environment variables, and whether a reverse proxy is dropping authentication information.
3. How should context overflow be handled?
Trim historical messages first, removing irrelevant attachments and duplicated passages. Then summarize long documents in chunks or apply retrieval. If that is still insufficient, switch to a long-context model. Do not try to solve input overflow by raising max_tokens.
4. Should timeouts be retried?
Retry connection failures and read timeouts a limited number of times, with exponential backoff and a cap. For operations with side effects, confirm whether they already executed to avoid duplicate orders or duplicate writes.
5. Where can I find the request_id?
Check the response headers and body first; field names depend on the actual interface. If neither was recorded, look in the console's model monitoring logs, provided inference logging was enabled. When contacting support, provide both the trace_id and a minimal reproduction request.
Next steps
Create a test key on the ZSQH AI Gateway, rehearse 401, 404, 429, context overflow, and timeout scenarios once each, and then connect production monitoring. Available models and billing methods are listed on the model pricing page.
