Claude Code 提示 API key 无效怎么解决
Claude Code 显示 invalid API key,但您明明在付费订阅?检查 VPS 中残留的 ANTHROPIC_API_KEY,了解为什么 /login 无法覆盖它。
Claude Code 显示 API key 无效错误的原因
Claude Code 显示 Invalid API key 可能有两种不同原因,对应的修复方法完全相反。第一种情况是,您确实想使用 API key,但该 key 错误、已撤销,或属于其他账户。第二种情况是,您本来不想使用 key,但服务器环境中残留的 ANTHROPIC_API_KEY 优先级高于您登录使用的订阅。根据 Anthropic 截至 2026 年 9 月的文档,第二种情况的说明很明确:即使您已经登录,环境中设置的 key 仍会替代 Claude Pro、Max、Team 或 Enterprise 订阅。
在修改任何内容前,先确认您属于哪种情况。启动 Claude Code,然后运行 /status。文档说明,其中有一行 Login method,用于显示您的订阅账户;如果正在使用 API key,还会出现一行 API key。如果您在一台只运行过 /login 的服务器上看到 API key 行,问题就在环境变量中,重新进行身份验证不会修改它。
下面的所有内容都是供您在自己的服务器上运行的命令。先查看输出,再执行后续操作。
凭据顺序,以及为什么 /login 无法解决问题
存在多个凭据时,Claude Code 会按文档规定的顺序选择凭据:
- 云服务商凭据,前提是已设置
CLAUDE_CODE_USE_BEDROCK、CLAUDE_CODE_USE_VERTEX或CLAUDE_CODE_USE_FOUNDRY。 ANTHROPIC_AUTH_TOKEN变量,该变量会作为Authorization: Bearer标头发送。ANTHROPIC_API_KEY变量,该变量会作为X-Api-Key标头发送。apiKeyHelper脚本的输出。CLAUDE_CODE_OAUTH_TOKEN变量,其中包含来自claude setup-token的令牌。- Anthropic 配置文件和联合身份凭据。
/login写入的订阅 OAuth 凭据。
请从列表底部开始阅读。/login 写入的是优先级最低的凭据。在 Linux 上,该凭据会写入 ~/.claude/.credentials.json,文件模式为 0600。上方的所有环境凭据优先级都更高。因此,重新登录只会刷新当前会话不会使用的凭据:登录成功了,但凭据没有生效。这就是看似合理的修复方法不起作用的原因。
交互式会话还会增加一个容易引起混淆的步骤。文档说明:如果环境中存在 API key,系统会提示您批准或拒绝一次,并记住您的选择。您几个月前确认的选择仍然有效。您可以通过 /config 中的“使用自定义 API key”切换开关修改该选择,但只有在环境中设置了 ANTHROPIC_API_KEY 时才会显示该开关。非交互模式是指脚本或 cron 作业中的 claude -p,此时完全不会显示提示:只要存在该 key,系统就始终使用它。
如何在 VPS 上找到遗留的 ANTHROPIC_API_KEY?
首先确认它存在于启动 Claude Code 的 shell 环境中。
env | grep -i anthropic然后运行 Anthropic 官方故障排查页面提供的修复命令。该命令也可用于验证问题:
unset ANTHROPIC_API_KEY
claude如果 Claude Code 启动,并且 /status 现在显示您的订阅信息,就可以确认问题原因。下一个 shell 中该变量会再次出现,因为 unset 只会修改执行它的 shell。本节其余内容介绍如何找到设置该变量的位置。
Shell 配置文件和系统范围的环境文件
grep -rn ANTHROPIC ~/.bashrc ~/.bash_profile ~/.profile ~/.zshrc \
~/.config/fish/config.fish /etc/environment /etc/profile /etc/profile.d/ 2>/dev/nullAnthropic 的页面列出了 ~/.zshrc、~/.bashrc 和 ~/.profile。在服务器上应扩大搜索范围。用户登录时,PAM(可插拔认证模块)会读取 /etc/environment,该文件对服务器上的每个用户都生效。这就是同事设置的密钥会出现在您会话中的原因。登录 shell 会执行 /etc/profile.d/ 中的文件。请注意,只有交互式 shell 才会读取 .bashrc,因此它不可能解释 systemd 服务中的故障。需要检查哪个文件,取决于 Claude Code 的启动方式。
systemd 单元
单元不会读取您的 shell 配置文件。其环境来自单元及其 drop-in 中的 Environment= 和 EnvironmentFile= 行。
systemctl cat claude-agent.service
systemctl show -p Environment claude-agent.servicesystemctl cat 会输出单元文件,随后输出 /etc/systemd/system/claude-agent.service.d/ 中的所有 drop-in。覆盖配置通常隐藏在这里。systemctl show -p Environment 会输出 systemd 实际传递给进程的环境。对于以您自己的用户身份运行的服务,请在两条命令中都添加 --user。编辑单元后,运行 sudo systemctl daemon-reload,然后重启服务。因为环境是在进程启动时组装的,正在运行的进程会继续使用启动时获得的环境副本。
超过配置修改生命周期的 tmux 和 screen 会话
这个问题经常浪费数小时。tmux 服务器会保留启动时的环境,新窗格从该服务器继承环境,而不是从当前 shell 继承。您从 .bashrc 中删除 export,打开一个新窗格,却仍然看到旧密钥。
tmux show-environment | grep -i ANTHROPIC
tmux set-environment -r ANTHROPIC_API_KEYset-environment -r 指定从 tmux 传递给新进程的环境中删除该名称,添加 -g 则会从服务器的全局环境中删除它。已经打开的窗格仍保留自己的副本,因为只能在进程内部修改该进程的环境。删除 export 后,可靠的做法是先分离会话,运行 tmux kill-server,再启动新会话。screen 的行为相同。在 VPS 上设置 长期运行的 tmux Claude Code 会话前,值得了解这一点,因为这类会话很容易在三轮配置修改后仍然继续运行。
要读取已经运行的进程环境,可以向内核请求:
tr '\0' '\n' < /proc/$(pgrep -n claude)/environ | grep -i anthropic该命令会输出进程在 exec 时获得的环境值,也就是进程实际使用的值。您必须是该进程的所有者或 root,才能读取该文件。pgrep -n claude 会选择最新的匹配项,因此存在多个进程时请检查 PID。
Docker 和 Compose
docker exec claude-agent env | grep -i anthropic
docker compose config第一条命令会显示运行中容器内的环境,包括来自 --env-file、environment: 块或镜像中内置的 ENV 行的内容。docker compose config 会输出解析变量后的 compose 文件,因此您看到的是实际传递的值,而不是写入的 ${ANTHROPIC_API_KEY} 占位符。两条命令都会将密钥输出到终端,因此请在可以清理记录的会话中运行。Compose 还会自动加载 compose 文件旁边的 .env 文件,无需额外指定。这通常是没人记得添加的密钥的来源。
经过所有 shell 修复仍然存在的设置文件
Claude Code 设置文件包含 env 块,文档明确说明了冲突规则:如果同一个变量同时设置在 shell 和设置文件的 env 块中,则使用设置文件中的值。写入其中的密钥优先于您输入的所有 unset。
grep -rn ANTHROPIC ~/.claude/settings.json .claude/settings.json .claude/settings.local.json 2>/dev/null除了用户设置文件,也要检查项目文件。.claude/settings.json 通常会提交到版本库,因此所有克隆该仓库的人都会获得它。组织还可以下发托管设置,其优先级高于您自己的文件。如果发现无法删除的密钥,请联系组织管理员。
另一条分支:密钥确实错误
如果 /status 显示的是 API 密钥,而且这是预期结果,请直接按错误信息处理。Anthropic 的错误参考文档列出了 Invalid API key 的以下原因:
- 密钥格式错误或不正确。
- 密钥已被撤销或已过期。
- 密钥属于其他组织或账户。
在不将密钥打印到终端回滚记录中的情况下检查其值:
echo "len=${#ANTHROPIC_API_KEY} tail=${ANTHROPIC_API_KEY: -6}"如果长度比预期多 1 或 2 个字符,通常表示复制粘贴时带入了行尾换行符或引号,或者 $(cat keyfile) 捕获了文件末尾的换行符。该值会作为 X-Api-Key 请求头发送,因此多出的字符意味着发送的凭据不是你创建的密钥。
检查同一输出中的 ANTHROPIC_AUTH_TOKEN,因为它按顺序位于 API 密钥之前。代理测试遗留的 bearer token 可能意味着你正在修复的密钥根本不是实际发送的凭据。还应查看该输出中的 ANTHROPIC_BASE_URL,因为旧值可能会将客户端指向已经不存在的网关。关于请求头层面的整体关系,请参阅Anthropic API 密钥身份验证的工作方式,其中介绍了这些字段各自携带的内容。在决定这台机器究竟应保存哪种凭据之前,请先阅读订阅登录与 API 密钥之间的取舍。
此错误不是容量问题。如果会话已完成身份验证,但工作过程中请求失败,那么你遇到的是模型过载错误,无需更换凭据。
为什么我的 apiKeyHelper 脚本失败?
apiKeyHelper 是一个设置项,用于指定 Claude Code 获取凭据时运行的脚本。它适用于轮换令牌或短期令牌,例如从 vault 获取的密钥。该脚本只需满足一个简单约定:将当前密钥输出到标准输出,并成功退出。文档说明,如果脚本退出时返回错误、超时或没有输出内容,请求会在三次尝试内因 Your apiKeyHelper script is failing 失败。
手动运行脚本,并检查这两个方面:
out=$(/usr/local/bin/anthropic-key.sh)
echo "exit=$? len=${#out} tail=${out: -6}"即使密钥输出正确,非零退出状态仍表示失败。如果辅助脚本在密钥前向标准输出打印 Fetching credential...,也会导致失败,因为该行会成为凭据的一部分。请将进度消息发送到标准错误。
然后,按服务运行脚本的方式测试:
env -i HOME="$HOME" PATH=/usr/bin:/bin /usr/local/bin/anthropic-key.sh
echo "exit=$?"env -i 会在几乎为空的环境中启动脚本。如果辅助脚本调用 aws、vault 或 gcloud,而这些命令位于您的 .bashrc 添加到 PATH 的目录中,那么手动测试时可以正常运行,但实际运行时会失败,因为运行中的 Claude Code 进程从未读取您的 .bashrc。请确保脚本具有可执行权限,并确保脚本调用的所有内容都使用绝对路径;或者在脚本本身中设置 PATH。
服务器上还需要注意另外两个已记录的行为。Claude Code 默认会在五分钟后重新运行辅助脚本,CLAUDE_CODE_API_KEY_HELPER_TTL_MS 可设置其他间隔。因此,启动时正常、运行一小时后失败的配置,问题出在刷新,而不是启动。 如果辅助脚本返回密钥所需时间超过十秒,Claude Code 会在提示栏中显示警告,并注明经过的时间。该提示表示调用速度较慢,并不表示调用已损坏;它是在超时转为错误前发出的早期警告。
您确实要在这台主机上使用 API key 吗?
解决方法不一定是删除它。如果机器需要单独计费,请保留该 key:
- 计费到 Console 的 VPS 上运行无人值守 agent,不会消耗个人订阅额度。
- 非交互式运行中,
claude -p没有终端来批准任何操作;只要存在该 key,系统就始终使用它。 - 未关联任何订阅的机器。
- 共享机器或客户机器,根本不应存储个人订阅登录信息。
通常由成本决定如何选择,API 与订阅的价格对比可用于评估。
如果主机归您所有,且您已经在支付订阅费用,请删除该 key。然后确保删除操作持久生效。不要将 key 导出到 ~/.bashrc,因为每个交互式 shell 都会继承它;应只将 key 提供给需要它的服务:
[Service]
EnvironmentFile=/etc/claude-agent.env将该文件的权限保持为 600,并将所有者设为运行该服务的用户。交互式会话看不到该文件,因此您自己的 claude 仍会使用订阅,而服务继续使用该 key。如果需要在没有浏览器的环境中使用订阅凭据,claude setup-token 会输出 OAuth token,供您粘贴到 CLAUDE_CODE_OAUTH_TOKEN 中。依赖它之前,应了解其文档说明的限制:它只能发起模型请求,因此无法使用 Remote Control 会话和 claude.ai 连接器。按机器确定一次该选择,并将其写入 unit 文件,才能避免本页所述的故障,因为该故障始于一个没人记得设置的 key。该凭据配置完成后能访问哪些内容,则是另一项工作,详见在 VPS 上安全运行 Claude Code。
在使用强制清理命令前,请注意这一点。/logout 会删除已存储的凭据。文档还说明,它会同时清除已保存的 MCP(模型上下文协议)服务器登录信息和插件密钥,因此之后需要重新授权。
FAQ
为什么我已付费订阅,Claude Code 仍提示 API 密钥无效?
因为环境中的 ANTHROPIC_API_KEY 优先级高于订阅登录。Anthropic 文档说明,只要环境中设置了密钥,Claude Code 就会使用该密钥,而不会使用您的 Pro、Max、Team 或 Enterprise 订阅,即使您已经登录。在非交互模式下,只要存在 -p,始终会使用该密钥。运行 /status,查看当前会话选择了哪项凭据。如果出现 API key 行,而您从未有意设置过该项,请运行 unset ANTHROPIC_API_KEY,然后再次启动 claude,以确认原因。
运行 /login 能解决 API 密钥无效错误吗?
变量仍处于设置状态时不能解决。/login 会写入订阅 OAuth 凭据,而这些凭据在 Claude Code 的凭据优先级中位于底部,优先级低于环境变量和 apiKeyHelper。登录虽然成功,但随后会被跳过,因此重复登录不会改变结果。请从设置该变量的位置将其删除,或者在 /config 中关闭“使用自定义 API 密钥”开关。文档说明,只有在环境中设置了 ANTHROPIC_API_KEY 时才会显示该开关。
如何查看 Claude Code 使用的身份验证方式?
在会话中运行 /status。文档说明,Login method 行表示您的订阅账户;使用 API 密钥时,会出现 API key 行。将其与启动 Claude Code 的同一 shell 中的 env | grep -i anthropic 进行比较。如果服务或容器运行 Claude Code,请改用 tr '\0' '\n' < /proc/<pid>/environ 读取进程环境,因为运行中的进程会保留启动时获得的环境,而不是当前 shell 的环境。
我的 apiKeyHelper 脚本手动运行正常。为什么 Claude Code 仍然失败?
通常是环境或退出状态导致的。Claude Code 从自身进程运行该辅助脚本,但该进程没有读取您的 shell 配置文件。因此,依赖 .bashrc 中 PATH 条目的辅助脚本会在 Claude Code 中失败,却能在终端中正常运行。使用 env -i HOME="$HOME" PATH=/usr/bin:/bin /path/to/helper 测试,并在之后检查 echo $?。文档所述的失败情况包括脚本以错误退出、超时或没有输出,错误会显示为 Your apiKeyHelper script is failing。除密钥外,写入标准输出的任何内容都会成为凭据的一部分,因此进度信息应发送到标准错误。