SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

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 年 10 月的文档,第二种情况的说明很明确:一旦您批准使用环境中设置的 key,即使已经登录,该 key 也会替代您的 Claude Pro、Max、Team 或 Enterprise 订阅;使用 claude -p 时,只要 key 存在,就始终会使用该 key。

在修改任何内容前,先确认您属于哪种情况。启动 Claude Code 并运行 /status。文档说明,其中会显示一个 Login method 行,用于显示您的订阅账户;如果正在使用 API key,还会显示一个 API key 行。如果您只在某台服务器上运行过 /login,但看到了 API key 行,请检查环境、设置和 apiKeyHelper;重新进行身份验证不会删除这些凭据。

下面的所有内容都是供您在自己的服务器上运行的命令。先查看输出,再采取操作。

凭据优先级,以及为什么 /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_PROFILE 明确选择的 Anthropic 配置、通过环境变量选择的联合身份凭据,以及使用 oidc_federation 认证的活动配置或默认配置。
  • /login 写入的订阅 OAuth 凭据。
  • 使用 user_oauth 认证的活动 Anthropic 配置或默认配置,除非 ANTHROPIC_PROFILE 明确选择该 user_oauth 配置。

从列表底部开始看。/login 写入订阅 OAuth 凭据;在 Linux 上,这些凭据存储在 ~/.claude/.credentials.json 中,文件模式为 0600。订阅 OAuth 凭据的优先级高于使用 user_oauth 认证的活动或默认 user_oauth 配置,除非 ANTHROPIC_PROFILE 明确选择该配置,但低于环境凭据和 apiKeyHelper。环境中已批准的 API key 仍然优先于您的订阅登录。因此,重新登录只会刷新当前会话根本不会使用的凭据:登录成功了,但它没有生效。这就是显而易见的修复方法不起作用的全部原因。使用 CLAUDE_CODE_OAUTH_TOKEN 时,/login 会将当前会话切换到新的登录,但新会话会再次读取该变量,直到您将其移除。已登录的 Claude apps 网关会话不属于此优先级顺序;它使用自己的网关令牌,而不是这些凭据,即使已设置云服务商变量也是如此。

交互式会话还会增加一个容易造成混淆的步骤。文档说明,系统会提示您批准或拒绝环境中找到的 API key,且会记住您的选择。如果您几个月前批准了该 key,该批准仍然有效,因此该 key 会继续优先于您的登录。如果您拒绝了该 key,系统会忽略它而不再询问,于是出现相反的问题:变量已设置,env 显示了该 key,但会话始终不使用它。您可以在 /config 中通过 “Use custom API key” 切换该选择;只有在环境中设置了 ANTHROPIC_API_KEY 时,才会显示此切换项。在非交互模式下,也就是脚本或 cron job 中的 claude -p,系统完全不会提示:只要 API 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/null

Anthropic 的页面列出了 ~/.zshrc、~/.bashrc 和 ~/.profile。在服务器上,应扩大搜索范围。登录用户的 PAM(可插拔认证模块)配置启用 pam_env 模块后,该模块会读取 /etc/environment,系统范围的密钥就是通过这种方式进入会话的。登录 shell 的 profile 加载 /etc/profile.d/ 中的文件时,这些文件会执行。systemd 服务不会自动读取 .bashrc;请检查其命令是否显式启动 shell 或加载 profile。需要检查哪个文件,取决于 Claude Code 的启动方式。

systemd 单元

单元不会读取您的 shell profile。其环境包括单元及其 drop-in 中的 Environment= 和 EnvironmentFile= 行,以及服务管理器提供的变量。

systemctl cat claude-agent.service
systemctl show -p Environment claude-agent.service

systemctl cat 会先输出单元文件,再输出其 drop-in,包括 /etc/systemd/system/claude-agent.service.d/ 下的覆盖配置。systemctl show -p Environment 会显示单元的 Environment= 赋值;还应检查所有 EnvironmentFile= 文件,因为进程启动时会单独读取这些文件的内容。对于以您自己的用户身份运行的服务,请在两个命令中都添加 --user。编辑单元后,运行 sudo systemctl daemon-reload 并重启服务,因为环境会在进程启动时组装,运行中的进程会继续使用启动时获得的环境副本。

超过配置修改生命周期的 tmux 和 screen 会话

这个问题可能耗费数小时。tmux 服务器会保留启动时的环境,新窗格会继承合并后的全局环境和会话环境。您从 .bashrc 中删除 export、打开一个新窗格,但旧密钥仍然存在。

tmux show-environment | grep -i ANTHROPIC
tmux set-environment -r ANTHROPIC_API_KEY

set-environment -r 标记要从 tmux 传递给新进程的环境中删除的变量名,添加 -g 则会从服务器的全局环境中执行相同操作。已经打开的窗格仍保留自己的副本,因为进程环境只能从进程内部修改。删除 export 后,可靠的做法是先分离会话,运行 tmux kill-server,再启动新会话。在 VPS 上设置 长期运行的 tmux Claude Code 会话前,应该了解这一点,因为这类会话正是会在多轮配置修改后仍继续运行的进程。

要读取已经运行的进程的环境,请向内核请求:

tr '\0' '\n' < /proc/$(pgrep -n claude)/environ | grep -i anthropic

该命令会输出进程在 exec 时获得的变量值;它不会反映之后的变化,例如 Claude Code 从设置中加载的值。您必须是进程所有者或 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 默认还会从项目目录加载 .env 文件,用于变量插值;当 Compose 配置将其中的值传递出去时,该值就会进入容器。

每次修复 shell 后仍然存在的设置文件

Claude Code 设置文件包含 env 块,文档明确说明了冲突处理方式:同一个变量同时设置在 shell 和设置文件的 env 块中时,大多数会话会使用设置文件中的值。例外是由 Claude Desktop 应用或自托管环境运行器启动的会话,此时启动环境优先。对于在服务器终端中启动的 claude,其中写入的密钥优先于您输入的所有 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 · Fix external API key 表示 API 拒绝了来自 ANTHROPIC_API_KEY 或 apiKeyHelper 脚本的密钥,或者 Claude Code 在发送前阻止了该密钥。针对这一错误,请检查:

  • 检查密钥中是否有拼写错误。
  • 在 Console 中确认该密钥尚未被撤销。
  • 确认 direnv、dotenv shell 插件或 IDE 终端等工具没有从项目的 .env 文件中加载过期密钥。

查看该值时,不要将其打印到终端回滚记录中:

echo "len=${#ANTHROPIC_API_KEY} tail=${ANTHROPIC_API_KEY: -6}"

如果长度比预期多 1 或 2 个字符,通常表示复制粘贴时一并带入了换行符或引号,或者密钥文件使用 Windows 换行符保存,留下了回车符。使用 $(cat keyfile) 读取文件时,命令替换输出末尾的普通换行符会被 Bash 删除,因此不会保留该换行符。但换行符前的回车符不会被删除,所以使用 Windows 换行符的文件仍会在变量中留下一个额外字符。当前版本会在发送前捕获请求头无法携带的字符:当消息继续显示 Fix external API key,并带有类似 Invalid X-Api-Key header value from ANTHROPIC_API_KEY: it contains a line break 的说明时,Claude Code 已停止请求,API 根本没有收到该密钥。弯引号也会被同一检查捕获,但直引号是合法的请求头字符,因此会作为 X-Api-Key 请求头的一部分发送,而实际发送的凭据并不是你创建的密钥。

还要在相同输出中检查 ANTHROPIC_AUTH_TOKEN,因为它在顺序上位于 API 密钥之前。代理测试遗留的 bearer token 表示你正在修复的密钥根本不是实际发送的凭据。也应查看该输出中的 ANTHROPIC_BASE_URL,因为旧值可能会将客户端指向已经不存在的网关。有关请求头层面的完整说明,请参阅Anthropic API 密钥认证的工作方式,其中介绍了这些字段分别承载的内容。在决定这台机器究竟应保存哪种凭据之前,请阅读订阅登录与 API 密钥之间的取舍。

此错误不表示容量不足。如果请求因 529 Overloaded 失败,请查看模型过载错误,无需更改凭据。

为什么我的 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...,同样会失败:从 v2.1.227 开始,Claude Code 会拒绝包含密钥以外任何内容的输出,并报告辅助脚本 returned output that cannot be used as an API key;旧版本则会将该行作为凭据的一部分发送。请将进度消息改为发送到标准错误。在会话中,/status 会显示一行 apiKeyHelper,其内容为 Failing,其中包含最近一次的退出码和错误输出。

然后,按服务的运行方式测试脚本:

env -i HOME="$HOME" PATH=/usr/bin:/bin /usr/local/bin/anthropic-key.sh
echo "exit=$?"

env -i 会使用几乎为空的环境启动脚本。如果辅助脚本从 .bashrc 添加到 PATH 的目录中调用 aws、vault 或 gcloud,那么手动测试时可以正常运行,但在启动环境不包含该目录的服务中会失败。确保脚本具有可执行权限,并确保脚本调用的所有内容都使用绝对路径;或者在脚本内部设置 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 key 无效?

因为环境中的 ANTHROPIC_API_KEY 在获得批准后,其优先级高于订阅登录凭据。Anthropic 文档说明,即使您已登录,设置在环境中的已批准 key 仍会替代 Pro、Max、Team 或 Enterprise 订阅;在非交互模式下,如果存在 -p,则始终使用该 key(前提是该 key 存在)。在 Claude Code 中运行 /status,查看会话选择了哪项凭据。如果出现 API key 行,而您从未主动设置过该项,请运行 unset ANTHROPIC_API_KEY,然后再次启动 claude,以确认原因。

运行 /login 能解决 API key 无效错误吗?

如果仍在使用已批准的环境 API key,则不能。/login 写入的订阅 OAuth 凭据低于环境凭据和 apiKeyHelper,但高于活动或默认的 user_oauth 配置;除非 ANTHROPIC_PROFILE 明确选择该配置。登录会成功,但随后会被跳过,因此重复登录不会改变结果。请从设置该变量的位置将其删除,或在 /config 中关闭 “Use custom API key” 开关。文档说明,只有在您的环境中设置了 ANTHROPIC_API_KEY 时,该开关才会显示。

如何查看 Claude Code 使用的身份验证方法?

在会话中运行 /status。文档说明,其中会显示 Login method 行,表示您的订阅账户;使用 API key 时,还会出现 API key 行。将其与启动 Claude Code 的同一 shell 中的 env | grep -i anthropic 进行比较。如果服务或容器运行 Claude Code,请使用 tr '\0' '\n' < /proc/<pid>/environ 检查其启动环境;该文件显示 exec 时提供的值,因此还应检查 Claude Code 随后加载的设置文件中的值。

我的 apiKeyHelper 脚本可以正常运行。为什么 Claude Code 仍然失败?

通常是环境或退出状态导致的。Claude Code 使用自己的进程环境运行该 helper,因此服务如果缺少终端环境中的 PATH 条目,就无法找到您在终端中测试时可以正常运行的命令。使用 env -i HOME="$HOME" PATH=/usr/bin:/bin /path/to/helper 进行测试,然后检查之后的 echo $?。文档所述的失败情况包括:脚本以错误退出、超时、没有输出,或输出了除 key 以外的内容;此时会显示为 Your apiKeyHelper script is failing。从 v2.1.227 开始,标准输出中的 banner 或日志行会直接导致 helper 失败,因此应将进度消息发送到标准错误。

这篇文章对您有帮助吗?