Claude Code のエラー

Failed to authenticate. API Error: 401 API key is invalid.

結論

APIキーは読み込まれたが拒否された状態。表示がNot logged inなら鍵自体が読まれておらず、原因も直し方も別になる。

確認した版 Claude Code v2.1.259
確認日 2026年9月3日
最終更新 2026年9月3日
根拠 実機で確認

エラー文字列

Claude Code
Failed to authenticate. API Error: 401 API key is invalid.

⚠️ 標準エラーではなく標準出力に出ます。終了コードは 1 です。

何が起きているか

⭐ **鍵は見つかっています。**見つかった鍵を API に送り、API 側が拒否した状態です。

「見つからなかった」場合とは別のメッセージが出ます。どちらが出ているかで、見る場所が変わります。

表示 意味 見る場所
Failed to authenticate. API Error: 401 API key is invalid. 鍵は読まれた。API が拒否した 鍵の値
Not logged in · Please run /login 鍵が1つも見つからなかった 鍵の渡し方(設定ファイル・環境変数)

v2.1.238 で実測しています。環境変数 ANTHROPIC_API_KEY に無効な値を入れた場合と、 settings.jsonenv.ANTHROPIC_API_KEY に同じ値を入れた場合のどちらでもこのメッセージになりました。

⚠️ つまり、このメッセージが出ている時点で「設定は効いている」ということです。 設定ファイルの書き方を疑う必要はありません。疑うのは値そのものです。

直し方

1. 実際に使われている鍵を確認する

Windows(PowerShell)

if ($env:ANTHROPIC_API_KEY) {
  "長さ: {0}" -f $env:ANTHROPIC_API_KEY.Length
  "先頭: {0}" -f $env:ANTHROPIC_API_KEY.Substring(0, [Math]::Min(12, $env:ANTHROPIC_API_KEY.Length))
  "前後の空白や改行: {0}" -f ($env:ANTHROPIC_API_KEY -ne $env:ANTHROPIC_API_KEY.Trim())
} else { "ANTHROPIC_API_KEY は設定されていません" }

macOS / Linux

printf '長さ: %s\n' "${#ANTHROPIC_API_KEY}"
printf '先頭: %.12s\n' "$ANTHROPIC_API_KEY"
printf '%s' "$ANTHROPIC_API_KEY" | od -c | tail -2   # 末尾に \n や \r が無いか

⚠️ 鍵の全体を画面に出さないこと。 ログや画面共有に残ります。長さと先頭数文字で足ります。

2. 前後の空白・改行を取り除く

CI のシークレットを貼り付けるときに、末尾の改行が一緒に入ることがあります。

export ANTHROPIC_API_KEY="$(printf '%s' "$SECRET_VALUE")"

Windows(PowerShell)

$env:ANTHROPIC_API_KEY = $env:ANTHROPIC_API_KEY.Trim()

3. 鍵の種類が合っているか確認する

変数 入れるもの
ANTHROPIC_API_KEY コンソールで発行した API キー
CLAUDE_CODE_OAUTH_TOKEN Claude の契約を使う場合の OAuth トークン

⚠️ **OAuth トークンを ANTHROPIC_API_KEY に入れると拒否されます。**入れる先を取り違えていないか確認してください。

4. 鍵が失効していないか確認する

コンソールで無効化・再発行された鍵は、値が残っていても拒否されます。 .env や CI のシークレットに古い鍵が残っていないか確認してください。

5. 複数の場所に鍵が書かれていないか確認する

環境変数と設定ファイルの両方に書いてあると、どちらが使われているのか分からなくなります。

まず片方を消してから試すのが確実です。

unset ANTHROPIC_API_KEY
claude -p "hi"

Not logged in · Please run /login に変われば、消したほうが使われていたということです。

再発防止

  • Not logged in401 を区別する。 前者は渡し方の問題、後者は値の問題
  • CI では鍵を Trim() してから渡す。末尾の改行はシークレット貼り付けで混入する
  • 鍵を環境変数と設定ファイルの両方に書かない。片方に決める
  • claude -p終了コードを見る。このメッセージは標準出力に出るため、回答として受け取ってしまう

この手順で直りませんでしたか?

環境を添えて報告いただければ、追加の原因を検証してこのページに反映します。

エラーを報告する