Qwen Code: error 401 invalid access token or token expired
A 401 in Qwen Code often means a stale Qwen OAuth login or a key sent to the wrong address. Step-by-step diagnosis and a switch to your own key.
5 min · · errors · агенты
The message "Qwen Code internal error: 401 invalid access token or token expired" (other clients show it as "Qwen API error: 401 invalid access token or token expired") says one thing: the server that answered did not accept the credentials. The question is which server it is and what credentials it saw. Below is the diagnostic order and a way to move to your own OpenAI-compatible key so the agent works again. Checked against the Qwen Code documentation and Zukko gateway responses as of October 18, 2026.
Where this error comes from
The "token expired" text points to an access token with a limited lifetime. In Qwen Code, such tokens belonged to the Qwen OAuth mode: you logged in through the browser, credentials were cached on disk and refreshed automatically. According to the project documentation, the Qwen OAuth free tier was discontinued on April 15, 2026, and already saved tokens may keep working for a while, but new requests are rejected. So the most likely cause of "token expired" in today's build is that the agent is still trying to use the old OAuth login. This option is no longer selectable in the /auth dialog.
We did not find an exact line with this text in the documentation, so we do not claim it is always tied to OAuth. But the diagnostic scheme below fits both cases: first find out which login method is active, then replace it with a key.
Other causes of 401 unrelated to OAuth:
- the key was typed with a typo, a space, or truncated when copied;
- one service's key is sent to another service's address;
- an old
OPENAI_API_KEYremains in the environment and overrides the key fromsettings.json.
Step 1. Find out which login method is used
Start qwen and run /doctor: per the docs, this command checks the current authentication. Then open /auth and see what is offered. If you only see key-based entries (Alibaba cloud, third-party providers, Custom Provider), OAuth is no longer in the list, and you need a key.
If the interface does not open at all (it hangs after a failed authentication), the docs give a fix: remove the security.auth.selectedType field from ~/.qwen/settings.json (or from the project's ./.qwen/settings.json) and restart the program. It will offer a login method again.
Step 2. Check who is answering
The most common mistake during a switch: the address stayed from the old provider while the key is new (or vice versa). Check the variables:
echo "$OPENAI_BASE_URL"
echo "${OPENAI_API_KEY:0:8}"
echo "$OPENAI_MODEL"For Zukko the address must be https://api.zukko.pro/v1, and the key must start with fetch_. If OPENAI_BASE_URL holds an Alibaba address while the key is fetch_..., Alibaba returns the 401, and your Zukko account has nothing to do with it.
Qwen Code's source priority is: command-line flags, then shell environment variables, then the .env file, and last the env field in settings.json. So an old export OPENAI_API_KEY=... in ~/.zshrc beats what you wrote into settings.json. Open a new terminal and run the echo checks above.
Step 3. Test the key separately from the agent
One direct request saves an hour of guessing:
curl -i https://api.zukko.pro/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-5-5","messages":[{"role":"user","content":"ping"}]}'How to read the Zukko gateway response:
| Code | Meaning | What to do |
|---|---|---|
| 200 | key and model are fine | the problem is in the Qwen Code settings |
| 401 | wrong key | recheck the key, issue a new one if in doubt |
| 402 | insufficient balance | top up in the dashboard |
| 403 | the model is not in the key's allowed list (model_not_allowed_for_key) | allow the model in the key settings or change it |
| 404 | unknown model name (model_not_found) | compare the id with GET /v1/models |
| 429 | key limit exhausted or a model provider restriction | see the key limits in the dashboard |
More on authorization: the authentication documentation and the general guide to 401 invalid API key. The full key is shown only once at creation, so if it is lost, create a new one on the API keys page.
Step 4. Switch Qwen Code to your own key
A quick option with environment variables:
export OPENAI_API_KEY="fetch_your_key"
export OPENAI_BASE_URL="https://api.zukko.pro/v1"
export OPENAI_MODEL="claude-sonnet-5-5"
qwenA persistent option via ~/.qwen/settings.json. It is better to keep the key out of the file itself and put it in .qwen/.env (the docs recommend this: it has higher priority, and the file is easier to keep out of git):
{
"modelProviders": {
"openai": [
{
"id": "claude-sonnet-5-5",
"name": "Claude Sonnet 5.5 (Zukko)",
"baseUrl": "https://api.zukko.pro/v1",
"envKey": "ZUKKO_API_KEY"
}
]
},
"security": { "auth": { "selectedType": "openai" } },
"model": { "name": "claude-sonnet-5-5" }
}And in ~/.qwen/.env:
ZUKKO_API_KEY=fetch_your_keyThe name in model.name must match one of the id values in modelProviders. After starting qwen you can switch models with /model. If any of these fields is named differently for you (the format has changed between versions), check the authentication page in the Qwen Code documentation.
Make a test request and open the "Usage" section in the dashboard: the request should appear there.
What to keep in mind when switching
- Take prices and models from
GET https://api.zukko.pro/v1/models. For example, as of October 18, 2026:claude-sonnet-5-5costs $0.4 / $2 per 1M input and output tokens,deepseek-v4.1-flash$0.013 / $0.038,qwen3.8-max$0.088 / $0.238. - A key can have a daily and monthly dollar limit and a list of allowed models.
- Access from Russia goes through the gateway: the balance is topped up via SBP (the payment page adds 8.5% on top), MasterCard or crypto.
If the error remains after all steps while curl returns 200, the agent is reading an old configuration. Start qwen from a clean shell without extra variables and check .env files in the current and parent directories: Qwen Code takes the first one it finds.
FAQ
Why did the error appear suddenly when everything worked yesterday?
If you used the Qwen OAuth login, the reason is that the free tier was discontinued and cached tokens stopped being accepted. It is not a fault of your machine.
Can I "refresh the token" and continue with OAuth?
Per the documentation, no: this method is no longer offered and new requests through it are rejected. You need a key from any compatible service.
I get 401 with a fetch_... key too. What should I check?
The key and the address: OPENAI_BASE_URL must be https://api.zukko.pro/v1. Then run the curl from step 3 and make sure the key is accepted.
The error is gone but there are no replies
Check for 402 (balance) and 403 (model not allowed for the key). The agent may show them less clearly than curl.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- Cline "hit repeated tool call failures": causes and fixesThe message means the agent failed several tool calls in a row. Causes and a checking order, from the base URL to context size.
- opencode agents: setting up roles, models and toolsA custom agent in opencode is a role, a model and a set of permissions. A working config where a cheap model handles routine work and a stronger one edits code.
- OpenAI API Keys in the Open: Why You Should Not Use ThemWhere free keys on GitHub come from, why using them is dangerous for you and for the owner, and how to protect your own key from the same leak.
- GLM API Errors: Why the Request Fails and How to Fix ItA wrong model id, an overflowing 128K context, the key, the balance, limits: the typical causes of GLM API errors and a quick way to find yours.