Troubleshooting · 鑑權

401 Unauthorized — 多半不是你剛換掉的那把 Key

30 秒版
  1. 確認端點要的是哪個頭:ANTHROPIC_AUTH_TOKENAuthorization: BearerANTHROPIC_API_KEYx-api-key——設錯了 Key 是好的也會 401。
  2. env | grep -i anthropic 看有沒有舊值蓋住新值,然後重啟客戶端(只在啟動時讀一次)。
  3. 用 curl 發同樣請求:curl 通了但客戶端 401 = 客戶端沒讀到你以為的變數;curl 也 401 = 憑證或端點的問題。

客戶端連到相容端點時,中間有兩層各自獨立的認證,401 可能來自其中任何一層,而兩者的報錯文字一模一樣。重新生成自己的 Key 只處理得到其中一層——而且實際上那是比較少見的那一層。

你看到的報錯

以下任意一種
API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}

401 Unauthorized

Could not resolve authentication method. Expected either apiKey or authToken to be set.

{"error":{"message":"Invalid bearer token","type":"authentication_error"}}

四種都只表示「請求送到了,但伺服器不接受它帶的憑證」。沒有一種會告訴你是哪一層拒絕的——但措辭可以縮小範圍。

資訊它告訴你的事最可能的原因
invalid x-api-key伺服器讀到了 x-api-key 頭並拒絕了它的值Key 不對——或者端點要的是 Bearer token
Invalid bearer token伺服器讀到了 Authorization: Bearer 並拒絕了它的值Token 不對——或者端點要的是 x-api-key
Could not resolve authentication method客戶端在發出任何東西之前就放棄了兩個變數都沒設,或不是這個客戶端讀的那個
只有 401,沒有內容有東西拒絕了它,而且沒有解釋你不知道它在路徑上的某個代理或閘道器

兩層認證

誰對誰認證失敗時的表現誰能修
第一層你的客戶端 → 端點第一次請求就失敗,每次都失敗
第二層端點 → 它的上游供應商常是間歇性的,或在完全沒改配置時突然開始端點運營方

多數排錯文章只寫得到第一層——「檢查你的 Key」。這建議沒錯,但它解釋不了真正讓人困惑的那種情況:一小時前還好好的,而你什麼都沒動。出現這種情況時,問題不在第一層。

按這個順序排查

1 · 憑證真的進到請求裡了嗎#

複製貼上會夾帶看不見的東西——結尾換行、不換行空格、從聊天視窗帶出來的彎引號。

終端
printf '%s' "$ANTHROPIC_AUTH_TOKEN" | wc -c
printf '%s' "$ANTHROPIC_AUTH_TOKEN" | tail -c 20 | xxd | tail -2

位元組數比看得見的長度多一,就是結尾跟著個換行一起被複制進來了。

2 · 你設的變數,產生的是端點要的那個頭嗎#

這是四種裡最安靜的一種失敗,因為報錯資訊完全不會提示你

變數客戶端發出的請求頭
ANTHROPIC_API_KEYx-api-key: <值>
ANTHROPIC_AUTH_TOKENAuthorization: Bearer <值>

如果端點是靠 Authorization: Bearer 認證,而你設的是 ANTHROPIC_API_KEY,請求送達時根本沒有 Authorization。伺服器回 401,資訊說 Key 無效。Key 是好的,錯的是頭。反過來也會發生。

接 9Coding 時設 ANTHROPIC_AUTH_TOKEN,Key 以 sk-9c- 開頭。

3 · 你的 base URL 結尾,是客戶端預期的位置嗎#

客戶端會自己在你給的 base URL 後面接上路徑(/v1/messages/v1/chat/completions)。如果你配的 base URL 結尾已經帶了 /v1,請求就會打到 /v1/v1/messages。這通常回 404——但先認證再路由的閘道器會回 401

終端
echo "$ANTHROPIC_BASE_URL"

正確的值就是 https://api.9coding.com——結尾不要斜槓,不要帶 /v1

4 · 有沒有舊值蓋住了你剛設的#

寫在 shell 配置檔案裡的值、寫在專案配置檔案裡的值、以及當前這個 shell 裡的值,是三件不同的事。客戶端讀的是其中一個,你改的可能是另一個。

終端
env | grep -i anthropic

每一條都要看,不要只看你記得設過的那條。然後重啟客戶端——Claude Code 只在啟動時讀一次環境變數,長時間執行的程序會沿用它啟動時的環境。

5 · 把客戶端排除在外#

終端
curl -s -w '\n%{http_code}\n' https://api.9coding.com/v1/models \
  -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN"
  • curl 回 200、客戶端回 401 → 客戶端讀的不是你以為的那個變數,回到第 4 步。
  • curl 也回 401 → 問題在憑證或端點,不在客戶端。
  • curl 連狀態碼都拿不到 → 這不是認證問題,看連線錯誤

什麼時候這不是你的問題

以下四點同時成立,就是第二層的事,你這臺機器上沒有東西要修:

  • 今天早些時候還能用,
  • 你沒有改任何配置,
  • 指向同一個端點的其他客戶端也是一樣的錯,
  • 而且過一陣子會自己好。

在你自己的配置上再花一小時之前,先去看運營方的狀態頁與變更日誌。一個既不公開狀態頁也不公開變更日誌的端點,是你沒辦法排錯的端點——這件事本身就值得知道。我們的在狀態頁

提問題時請帶上 request id——9Coding 的報錯響應裡都有一個,形如 (request id: 2026...)。這個 id 加上時間戳、模型名和完整報錯文字,就能把那一次呼叫查出來。只說「用不了」的反饋沒法排查。

401 和 403 不是同一個問題

403 表示請求透過了認證然後被拒絕:賬號沒有那個模型、那個地區或那個功能的許可權。換 Key 保證沒用。見 403 Forbidden

相關報錯