You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Provider API: working CLI key starts returning 401 authentication_error mid-use (2026-10-29), re-login fixes it — no local change involved #1084
A long-lived CLI API key that was working normally started returning 401 authentication_error on every Provider API request on 2026-10-29, with no local change on my side. Re-signing in through the Studio CLI auth flow minted a new key that works immediately. Filing in case the revocation was unintentional (it overlaps the 2026-10-28 → 10-29 instability window) or affects other users.
Environment
Plan: GOAT
Client: command-code CLI credentials (~/.commandcode/auth.json), consumed through a local gateway that passes the key as Authorization: Bearer <key>
Not a quota problem: at failure time Credits showed ~$30 of $70 remaining, weekly window ~36.5 used with reset on 2026-10-30
Timeline (CST, UTC+8)
2026-10-28 22:55 — last successful request with the old key (HTTP 200; ~420 successful requests through this key during 10-28)
2026-10-29 00:03 — one request retried 8×, all 502 with "The socket connection was closed unexpectedly", then gave up
2026-10-29 08:59 — first try 502, second try 401: Command Code Plan: Invalid 'Authorization' header or token.
2026-10-29 09:00 onward — every request 401
What rules out a local cause
No credential/config file changed locally between 22:55 (working) and 00:03 (failing); mtimes are from 2026-10-28 13:54, hours before the break
Reproduced outside the gateway with a direct curl to https://api.commandcode.ai/provider/v1/chat/completions with the exact catalog model id → 401 {"error":{"message":"Invalid 'Authorization' header or token.","type":"authentication_error","code":"UNAUTHORIZED"}}
HTTP/1.1 401 Unauthorized
Date: Thu, 29 Oct 2026 01:42:14 GMT
x-trace-id: 13dccdb25d9d0223b447f5ccce52106e
CF-RAY: a51e7b84ad69c238-NRT
{"error":{"message":"Invalid 'Authorization' header or token.","type":"authentication_error","code":"UNAUTHORIZED"}}
Resolution (workaround)
Re-running the Studio CLI sign-in (https://commandcode.ai/studio/auth/cli?...) minted a fresh key (cli-2026-10-29T02-02-42) and requests immediately return HTTP 200 again. Same account, same plan, nothing else changed.
Happy to provide the userId of the affected key if needed. Related: #1040 (same error string, user-side cause there), #1060 (service instability in the same window).
Confirming this is not isolated — same failure window, same account-side symptoms, plus one detail that may answer the "was this intentional?" question in the original report.
2026-10-29 11:08 CST — replaced the key in our gateway; immediate recovery
This overlaps the reporter's window (last success 22:55 CST, first 401 at 08:59 CST) within ~13 minutes at the start.
The detail worth adding: two keys, two different error strings
We held two long-lived keys on the same GOAT account. Both stopped working in the same window, but the upstream message differs — and the difference is informative:
Key (masked)
Length
Upstream message
user_… (93 chars, previously disabled)
93
Your API key has expired. Log in again to get a new key: run cmd login, or create a new key in Command Code Studio.
user_… (92 chars, the one in active use)
92
Invalid 'Authorization' header or token.
The 93-char key is told it has expired — an explicit expiry verdict, not a generic auth rejection. That suggests at least one key was retired under a deliberate expiry/rotation path on the server side, rather than being collateral from the Cloudflare 1102 instability in #1060. It would be worth confirming whether both keys hit the same code path.
Ruled out on our side
Not a quota problem. Billing state at failure time and now (/alpha/billing/credits, /alpha/billing/subscriptions, read with the replacement key):
planId: individual-goat
status: active
currentPeriodEnd: 2026-11-07T07:24:07Z
monthlyCredits: 27.96 (of the $80 boosted deepseek-v4.1-flash allowance)
5-hour window: 0.14 / 14 used
weekly window: 17.96 / 35 used
No window exceeded, no balance exhaustion. Consistent with a 401 at the auth stage — the request never reached metering, so nothing was charged.
Not a local change. No credential or config file was modified in our gateway between the last success and the first failure. The only change after the failures began was replacing the key, which fixed it.
Not a request-shape problem. Results are identical across /provider/v1/chat/completions and /provider/v1/responses, and across models (deepseek/deepseek-v4.1-flash, gpt-5.6-luna, zai-org/GLM-5.3, moonshotai/Kimi-K3).
Traces
Old keys (failures), captured 2026-10-29 03:26 UTC:
Same account, same plan, same endpoint, same body, same egress host — only the key differs. So the credential itself is the rejected artifact, not the request.
Setup
A self-hosted gateway forwards the key as Authorization: Bearer <key> — the same shape as the original report's local gateway. /provider/v1/models returns 200 without auth validation, so it is not usable as a health signal here; a real inference call is the only reliable check.
Asks
Was the 92/93-char key expiry intentional? The has expired wording on one key suggests a rotation/expiry path was deliberately triggered. If so, please publish the policy — keys silently expiring with no advance signal is the part that costs us real time.
A proactive validity signal would prevent this class of outage. The Billing API reports the account as healthy while every request 401s (also noted in Billing API reports a healthy account while every request 400s with insufficient credits #1081), and command-code status reports "Authenticated" from the presence of a credential file rather than from a live check. Either a keyValid/canRequest-style field or a lightweight authenticated probe endpoint would let gateways fail over before burning requests.
Third independent report — same window, plus two details that may help pin this down.
Environment: Windows 11, CLI 1.88.2, headless runs (cmd -p) driven by a local scheduler.
Local timeline (UTC; the machine is UTC+3):
2026-10-28 16:00Z — last successful scheduled headless run.
2026-10-29 05:23:59Z — npm auto-update to 1.88.2 landed.
2026-10-29 05:27:53Z — first failure. Two scheduled runs died with Error: Authentication failed. Please run "cmdc login" first. (exit code 3). ~/.commandcode/auth.json was still present and still contained the key — no credential file was modified between the last success and the first 401. So the update is not the trigger (neither reporter above had one); on this machine it just made the failure visible 4 minutes earlier.
2026-10-29 05:39Z — cmdc login. The Studio flow minted a new CLI key, auto-named cli-2026-10-29T05-41-00.
2026-10-29 05:40:57Z — local auth.json rewritten by the manual-key branch of the login flow; cmdc whoami OK, every request 200 since.
Trace from the failing CLI session: 29dce525a47473ca06842518a6066788.
1. Revoked keys are hidden from the dashboard, which is what makes this unanswerable from the client side. Before re-login the Studio key list showed no keys at all — not a revoked/expired entry with a reason. From the UI it is impossible to distinguish "revoked on purpose 4 minutes ago" from "expired" from "never created". Listing revoked keys with a reason and a timestamp (even greyed out) would answer the core question of this issue without a support ticket.
2. On 1.88.2, cmdc status is a live check, not a file-presence check (relevant to ask 3 above). I verified this in an isolated HOME/USERPROFILE so the real credential was untouched:
current key with one character mutated (format still valid, key invalid) → cmdc status prints Not authenticated and exits 1; cmdc whoami behaves the same (Not authenticated. Please login);
unmutated key → Authentication verified, exit 0.
So an exit-code-based health probe does work on this version — it is what I gate scheduled runs on now. What would still help: a distinct exit code / message for "key revoked or expired" vs. "never signed in". A supervisor cannot tell them apart today, and that difference is exactly what decides between "re-authenticate" and "page a human".
3. A ~13-day age pattern? The reporter's key was cli-2026-10-16T07-27-19 — created 10-16, dead 10-29, ≈13 days. Our previous credential died in the same window, but I cannot date it exactly because auth.json was overwritten by the re-login. One more data point: the credential we held before was visibly longer and shaped differently from the 93-char user_… key that login mints now (observed in the dashboard; no local copy survived). If the key scheme changed and/or there is a TTL, it should be documented — and ideally the CLI should warn a few days before expiry, because a silent expiry takes down unattended jobs with no signal whatsoever.
Happy to provide the userId and the trace above privately.
Same failure mode here, on a paid GOAT plan and with quota nowhere near exhausted (Studio shows 5-hour window 0%, weekly 13%, monthly 75%, 2.4B tokens lifetime).
Two keys were retired server-side within 12 hours, and both distinct upstream messages mentioned above showed up on this single account:
Key A (92 chars, user_j616i1s…): last successful request 2026-10-28 17:45:46 CST (UTC+8). First 401 at 2026-10-29 04:01:32 CST: {"error":{"message":"Invalid 'Authorization' header or token.","type":"authentication_error","code":"UNAUTHORIZED"}}
It then disappeared from Studio → API keys.
Key B (92 chars, user_gxYcf5E…, created ~2026-10-29 04:00 CST): worked continuously 04:13–06:57:57 CST (446 successful requests). First 401 at 06:59:31 CST: Your API key has expired. Log in again to get a new key: run \cmd login`, or create a new key in Command Code Studio.`
— an explicit expiry verdict, roughly 2h50m after creation. Studio now lists it with an "expired" badge.
Key C (93 chars, created 13:46 CST): still working at the time of writing.
Reproduced outside the local gateway with plain curl against POST https://api.commandcode.ai/provider/v1/chat/completions (key A): HTTP 401 with the identical body, x-trace-id: 0282e57f4b1b75de8bafd830dca0c882, cf-ray: …-SIN.
Client chain: Cherry Studio 2.1.8 local OpenAI-compatible gateway → https://api.commandcode.ai/provider/v1, streaming, deepseek/deepseek-v4.1-flash, Windows 10 x64, single machine. Nothing changed locally between the last success and the first failure, and the stored key strings are intact (92 chars, same format as the working key in #1040).
So this is not quota, not a model/plan gate, and not a request-shape problem: keys are being retired server-side, one of them with an explicit "expired" verdict.
Questions:
Is there now an API-key TTL / rotation policy? The docs (Studio, Provider API, Security, Terms) and the Studio UI don't mention one. If it exists, what is the TTL, and why did a key created around 04:00 CST expire at 06:59?
Was the 2026-10-28 → 10-29 retirement wave an incident response, a key-format migration (92 → 93 chars), or a deliberate revocation?
Could the API/CLI surface a distinct "key expired — re-authenticate" state (as the newer message does) instead of a mid-use generic 401, and is there any advance notice by email or in-app?
Happy to share the account/key identifiers privately if useful.
Addendum to my report above — one state that is missing from this thread so far: the key list was empty, not "expired".
Details that don't match the other two cases:
Before re-login, Studio → API keys listed zero keys for the account. No expired badge, no greyed-out entry, no "removed" row — an empty list. The other report in this thread shows Studio can render a retired key with an explicit expired badge, so "expired" and "gone" appear to be two different end states, not the same one.
The CLI, meanwhile, collapses both into one message: Your API key may be invalid or expired. Run "cmdc login" to sign in again. (trace 29dce525a47473ca06842518a6066788). So from the client the user cannot tell "expired — re-authenticate" from "removed — something else happened".
The replacement credential minted at 2026-10-29T05:40:57Z is user_-prefixed, 93 chars, and has been healthy since (same account, same plan, no other change). That is consistent with the 92 → 93 char split noted above: the new-format key works.
Ask: was the previous key deleted, or expired-and-then-hidden? A key audit trail in Studio — created / expired / revoked / deleted, each with a timestamp and an actor (user vs system) — would answer this class of question in one screen, and would also make the next incident self-diagnosable without a support thread. Email or in-app notice on revocation would cover the "no advance signal" part.
Activity
FlyingDriver commentedon Oct 29, 2026
Confirming this is not isolated — same failure window, same account-side symptoms, plus one detail that may answer the "was this intentional?" question in the original report.
Timeline (CST / UTC+8)
2026-10-28 17:04:42 UTC) — last successful request, HTTP 2002026-10-29 01:12:58 UTC) — first401 authentication_errorThis overlaps the reporter's window (last success 22:55 CST, first 401 at 08:59 CST) within ~13 minutes at the start.
The detail worth adding: two keys, two different error strings
We held two long-lived keys on the same GOAT account. Both stopped working in the same window, but the upstream message differs — and the difference is informative:
user_…(93 chars, previously disabled)Your API key has expired. Log in again to get a new key: runcmd login, or create a new key in Command Code Studio.user_…(92 chars, the one in active use)Invalid 'Authorization' header or token.The 93-char key is told it has expired — an explicit expiry verdict, not a generic auth rejection. That suggests at least one key was retired under a deliberate expiry/rotation path on the server side, rather than being collateral from the Cloudflare 1102 instability in #1060. It would be worth confirming whether both keys hit the same code path.
Ruled out on our side
Not a quota problem. Billing state at failure time and now (
/alpha/billing/credits,/alpha/billing/subscriptions, read with the replacement key):No window exceeded, no balance exhaustion. Consistent with a 401 at the auth stage — the request never reached metering, so nothing was charged.
Not a local change. No credential or config file was modified in our gateway between the last success and the first failure. The only change after the failures began was replacing the key, which fixed it.
Not a request-shape problem. Results are identical across
/provider/v1/chat/completionsand/provider/v1/responses, and across models (deepseek/deepseek-v4.1-flash,gpt-5.6-luna,zai-org/GLM-5.3,moonshotai/Kimi-K3).Traces
Old keys (failures), captured 2026-10-29 03:26 UTC:
Control — the replacement key on the same request, ~19s later:
Same account, same plan, same endpoint, same body, same egress host — only the key differs. So the credential itself is the rejected artifact, not the request.
Setup
A self-hosted gateway forwards the key as
Authorization: Bearer <key>— the same shape as the original report's local gateway./provider/v1/modelsreturns 200 without auth validation, so it is not usable as a health signal here; a real inference call is the only reliable check.Asks
has expiredwording on one key suggests a rotation/expiry path was deliberately triggered. If so, please publish the policy — keys silently expiring with no advance signal is the part that costs us real time.command-code statusreports "Authenticated" from the presence of a credential file rather than from a live check. Either akeyValid/canRequest-style field or a lightweight authenticated probe endpoint would let gateways fail over before burning requests.Happy to provide account id and the full keys privately if that helps you look them up by server-side key record.
cenktekin commentedon Oct 29, 2026
Third independent report — same window, plus two details that may help pin this down.
Environment: Windows 11, CLI 1.88.2, headless runs (
cmd -p) driven by a local scheduler.Local timeline (UTC; the machine is UTC+3):
2026-10-28 16:00Z— last successful scheduled headless run.2026-10-29 05:23:59Z— npm auto-update to 1.88.2 landed.2026-10-29 05:27:53Z— first failure. Two scheduled runs died withError: Authentication failed. Please run "cmdc login" first.(exit code 3).~/.commandcode/auth.jsonwas still present and still contained the key — no credential file was modified between the last success and the first 401. So the update is not the trigger (neither reporter above had one); on this machine it just made the failure visible 4 minutes earlier.2026-10-29 05:39Z—cmdc login. The Studio flow minted a new CLI key, auto-namedcli-2026-10-29T05-41-00.2026-10-29 05:40:57Z— localauth.jsonrewritten by the manual-key branch of the login flow;cmdc whoamiOK, every request 200 since.29dce525a47473ca06842518a6066788.1. Revoked keys are hidden from the dashboard, which is what makes this unanswerable from the client side. Before re-login the Studio key list showed no keys at all — not a revoked/expired entry with a reason. From the UI it is impossible to distinguish "revoked on purpose 4 minutes ago" from "expired" from "never created". Listing revoked keys with a reason and a timestamp (even greyed out) would answer the core question of this issue without a support ticket.
2. On 1.88.2,
cmdc statusis a live check, not a file-presence check (relevant to ask 3 above). I verified this in an isolatedHOME/USERPROFILEso the real credential was untouched:cmdc statusprintsNot authenticatedand exits 1;cmdc whoamibehaves the same (Not authenticated. Please login);Authentication verified, exit 0.So an exit-code-based health probe does work on this version — it is what I gate scheduled runs on now. What would still help: a distinct exit code / message for "key revoked or expired" vs. "never signed in". A supervisor cannot tell them apart today, and that difference is exactly what decides between "re-authenticate" and "page a human".
3. A ~13-day age pattern? The reporter's key was
cli-2026-10-16T07-27-19— created 10-16, dead 10-29, ≈13 days. Our previous credential died in the same window, but I cannot date it exactly becauseauth.jsonwas overwritten by the re-login. One more data point: the credential we held before was visibly longer and shaped differently from the 93-charuser_…key that login mints now (observed in the dashboard; no local copy survived). If the key scheme changed and/or there is a TTL, it should be documented — and ideally the CLI should warn a few days before expiry, because a silent expiry takes down unattended jobs with no signal whatsoever.Happy to provide the userId and the trace above privately.
a404670637-ch commentedon Oct 29, 2026
Same failure mode here, on a paid GOAT plan and with quota nowhere near exhausted (Studio shows 5-hour window 0%, weekly 13%, monthly 75%, 2.4B tokens lifetime).
Two keys were retired server-side within 12 hours, and both distinct upstream messages mentioned above showed up on this single account:
user_j616i1s…): last successful request 2026-10-28 17:45:46 CST (UTC+8). First 401 at 2026-10-29 04:01:32 CST:{"error":{"message":"Invalid 'Authorization' header or token.","type":"authentication_error","code":"UNAUTHORIZED"}}It then disappeared from Studio → API keys.
user_gxYcf5E…, created ~2026-10-29 04:00 CST): worked continuously 04:13–06:57:57 CST (446 successful requests). First 401 at 06:59:31 CST:Your API key has expired. Log in again to get a new key: run \cmd login`, or create a new key in Command Code Studio.`— an explicit expiry verdict, roughly 2h50m after creation. Studio now lists it with an "expired" badge.
Reproduced outside the local gateway with plain curl against
POST https://api.commandcode.ai/provider/v1/chat/completions(key A): HTTP 401 with the identical body,x-trace-id: 0282e57f4b1b75de8bafd830dca0c882,cf-ray: …-SIN.Client chain: Cherry Studio 2.1.8 local OpenAI-compatible gateway →
https://api.commandcode.ai/provider/v1, streaming,deepseek/deepseek-v4.1-flash, Windows 10 x64, single machine. Nothing changed locally between the last success and the first failure, and the stored key strings are intact (92 chars, same format as the working key in #1040).So this is not quota, not a model/plan gate, and not a request-shape problem: keys are being retired server-side, one of them with an explicit "expired" verdict.
Questions:
Happy to share the account/key identifiers privately if useful.
cenktekin commentedon Oct 29, 2026
Addendum to my report above — one state that is missing from this thread so far: the key list was empty, not "expired".
Details that don't match the other two cases:
expiredbadge, so "expired" and "gone" appear to be two different end states, not the same one.Your API key may be invalid or expired. Run "cmdc login" to sign in again.(trace29dce525a47473ca06842518a6066788). So from the client the user cannot tell "expired — re-authenticate" from "removed — something else happened".2026-10-29T05:40:57Zisuser_-prefixed, 93 chars, and has been healthy since (same account, same plan, no other change). That is consistent with the 92 → 93 char split noted above: the new-format key works.Ask: was the previous key deleted, or expired-and-then-hidden? A key audit trail in Studio — created / expired / revoked / deleted, each with a timestamp and an actor (
uservssystem) — would answer this class of question in one screen, and would also make the next incident self-diagnosable without a support thread. Email or in-app notice on revocation would cover the "no advance signal" part.dondiegorivera commentedon Oct 29, 2026
I have the same failure. First, my key was deleted. I recreated it yesterday, then by the morning it expired.
naymurdev commentedon Oct 29, 2026
@dondiegorivera sorry for that inconvenience, please create new API
vipulgupta2048 commentedon Oct 29, 2026
Thanks for the reports @cenktekin @dondiegorivera @hayashishungenn @a404670637-ch @FlyingDriver
All API keys were revoked for users. As a final precaution, we once again purged all API keys that you might created in the interim.
Services are back to normal now, please recreate your API keys, it should work now.
Context: https://discord.com/channels/1255220079029653626/1255287193656623266/1565143125503254560