Anthropic API Key 用不了?先读状态码:401/403/404/400/429 各是什么问题
「我的 Anthropic API key 用不了」这句话背后,几乎总是五个不同的问题穿着同一件外衣。其中四个跟 key 本身毫无关系。状态码会直接告诉你是哪一个,读它只要十秒——远少于重新生成一次 key 的时间,而重新生成通常什么也解决不了,因为 key 一开始就是好的。
本文先按「接口实际返回了什么」把故障分类,再讲那个最让人困惑的情况:环境里明明躺着一把完全有效的 key,请求却还是失败。
第一步:读状态码,诊断到这里就已经完成一半
每一次失败的调用都会返回一个 HTTP 状态码,以及一个带 type 字段的 JSON 错误对象。这两样东西合起来就能定位问题。在动手改任何东西之前,先把它们打印出来。
|
状态码 |
错误类型 |
它真正的含义 |
|---|---|---|
|
401 |
|
凭据缺失、格式错误、已吊销,或者放错了请求头。只有这一个才是「key 的问题」 |
|
403 |
|
key 有效且已通过认证,只是不被允许做这件事 |
|
404 |
|
key 没问题,是模型 ID 或接口路径写错了 |
|
400 |
|
key 没问题,是请求体或你所在组织的配置有问题 |
|
429 |
|
key 完全正常且正在工作,你只是超过了某个限额 |
只有第一行是 key 的问题。如果你因为后面四种里的任何一种去重新生成 key,那你只是用一把能用的凭据换了另一把能用的凭据,然后复现同一个故障。
请求 ID 同样重要。每个响应都带 request-id 响应头,各语言 SDK 也会把它挂在响应对象上。在开始试错之前先记下来——它是技术支持能追溯的东西,也能区分「请求到达了 Anthropic 并被拒绝」和「请求根本没到」。
401:真的是凭据出问题的那几种情况
即使落在 401 里,仍然要继续分叉,而最不显眼的那几条分支恰恰最费时间。
请求头和凭据类型对不上。 API key 放在 x-api-key 里;OAuth 访问令牌放在 Authorization 里作为 bearer token,同时还要带上 anthropic-beta: oauth-2025-04-20 这个 beta 头。两者不能互换。把一个能用的请求从 API key 改成 OAuth 令牌,改的是请求头而不只是换个值——而把 bearer token 粘进 x-api-key,返回的 401 和一把乱码 key 返回的一模一样,不会给你任何提示。
同时设置了两套凭据。 如果环境里 ANTHROPIC_API_KEY 和 ANTHROPIC_AUTH_TOKEN 同时存在,SDK 会把两个头都发出去,接口会拒绝这个请求。这一条相当刁钻:两个变量各自都是对的,没有任何东西过期,而解法是删掉其中一个。它最常出现在往一台已经在 shell 配置里导出了 key 的机器上再接 OAuth 之后。
key 已被吊销、轮换,或属于一个已删除的工作区。 发生这种情况时,key 字符串本身看不出任何区别。去控制台核对,而不是盯着这串值看。
空白字符与截断。 从文件里读出来带了行尾换行的 key,或者从换行显示的终端里复制出来的 key,是另一个字符串。拿你的进程实际加载到的长度和控制台里的长度对比,而不是只看开头几位。
403:认证通过了,但没有权限
403 意味着凭据被接受并识别了,接下来发生的是一次授权判定。常见成因有三种:这把 key 无权访问你指定的模型、组织层面存在限制、或者你在调用一个组织尚未获授权的 beta 功能。
区分方法很简单:把请求原封不动地重发一次,只把模型换成一个你确定线上在用的。如果成功了,凭据就是好的,问题被限定在模型或功能上——该去控制台检查 key 的权限与工作区归属,而不是检查 key 的值。
404:是模型 ID,不是 key
在消息接口上收到带 not_found_error 的 404,几乎总是模型字符串写错了。最容易中招的失误是标点:模型 ID 全程使用连字符,把某个连字符写成点,产生的 404 在凌晨两点疲惫的人眼里,和认证失败长得一模一样。
还有两个相关的坑。其一,不要凭着对旧文档的模糊记忆给当前的模型 ID 追加日期后缀——当前这些 ID 本身就是完整的。其二,已下线的模型同样返回 404,所以上个季度还跑得好好的代码,可能在凭据毫无变化的情况下开始「认证失败」。拿不准时,用模型列表接口把这把 key 实际能看到的模型列出来,从返回结果里复制一个 ID。
400:请求体,或者你所在组织的配置
400 属于请求问题,但其中两种变体常被误读成凭据故障,因为它们是每一次调用都失败,而不是偶尔失败。
第一种是新一代模型不再接受的参数。采样类参数和固定思考预算在当前这一代上已经移除,发送它们一律返回 400,跟你的 key 有多好毫无关系。如果一个原本正常的集成在升级模型之后立刻开始失败,第一个该查的是这里,而不是 key。
第二种是数据留存约束。某些模型要求组织或工作区把数据留存开到规定级别;低于该级别的组织,向这些模型发出的每一个请求都会返回 400——哪怕请求体完全合法、key 完全有效。错误信息里会明确提到留存,这就是判别点:读错误文本,而不是想当然认为 400 就等于 JSON 写坏了。
429:它正在正常工作,并且在告诉你这件事
429 恰恰证明你的 key 通过了认证。它是容量信号而不是凭据信号——同时也是被误报成「key 用不了」最多的一种,因为新组织从最低的速率限制档位起步,很小的负载就可能立刻撞到天花板。
读 retry-after 和 x-ratelimit-* 这几个响应头,看你越过的是哪一条限额;另外要知道各语言 SDK 默认已经会对 429 和 5xx 做退避重试。完整的排查——你到底撞上了哪一条独立计量的限额、各自怎么修——是另一个话题,见Anthropic API 速率限制。
那个制造「key 明明就在这儿却还是失败」的坑
这是最浪费时间的一类,而它的成因不是 key 写错了,而是你的进程实际取到了哪一份凭据。
各语言 SDK 与命令行工具按固定顺序解析凭据,先匹配到的胜出:ANTHROPIC_API_KEY,然后 ANTHROPIC_AUTH_TOKEN,然后由 ANTHROPIC_PROFILE 选中的配置档或此前登录留下的活跃 OAuth 档,然后是工作负载身份联合的那组环境变量,最后是磁盘上的默认配置档。
由此有三条推论,每一条都对应一个真实存在的 bug:
ANTHROPIC_API_KEY没设,不等于你没有凭据。 在命令行登录之后,不带参数的客户端构造函数照样能用,环境里一个变量都不需要。那种「检测到环境变量缺失就抛异常拒绝构造客户端」的代码,正在拒绝一台配置完全正确的机器。- 导出的 key 会遮蔽它下面的一切。 遗留在 shell 配置、Dockerfile 或 CI 密钥里的一把旧 key,会悄悄压过你刚刚登录成功的那个配置档。你登录成功了,也验证了登录状态,请求却仍然在用旧 key——因为环境变量的优先级高于配置档。
- 空值也算「已设置」。 尤其对联合身份凭据而言,
ANTHROPIC_API_KEY或ANTHROPIC_AUTH_TOKEN即使值是空字符串也会压过联合身份;而设了ANTHROPIC_PROFILE却指向一个不存在的档,是直接报错,不会自动落到下一个来源。
一条命令就能回答这件事:ant auth status,它会报出当前真正生效的来源与配置档。动手之前先跑它。如果它给出的来源和你预期的不一样,你已经在没改动任何凭据的情况下找到了 bug。
如果你是通过网关或中转在调用
如果你的请求不是直连 Anthropic,而是经过一个 OpenAI 兼容网关、一个中转层或企业出口代理,那么在做上面所有排查之前,先加一步:确认这个错误是哪一段产生的。
网关用它自己的凭据给你做认证,再用另一份凭据向上游认证自己。因此一个 401 可能诞生在两跳中的任意一跳,而两者的修法完全相反。判别方式是看响应体的形状——Anthropic 的错误对象带一个 type 字段,取值就是上面表格里那几个;网关自己的拒绝通常长得不一样,而且经常根本不是 JSON。一个 HTML 错误页绝不可能来自消息接口,它来自挡在前面的某个东西。超时,以及「返回 200 但错误裹在一个非标准信封里」,同理。
Base URL 是这件事的另一半。指向网关的客户端发出的是给该网关用的凭据;同一份代码指向默认端点时,这些凭据发到了 Anthropic,在那边毫无意义,于是返回 401。如果你靠改一个 base URL 变量来切换环境,凭据必须跟着一起切。这一层的结构见 Claude API 中转,接入路径与「权限在哪里被卡住」见 Anthropic Claude API 接入权限。
五分钟排查顺序
- 打印 HTTP 状态码、错误对象的
type,以及request-id。别再猜了,你现在已经知道类别。 - 若是 401:检查凭据放在哪个请求头里,以及是否同时设置了两个凭据环境变量。
- 确认进程实际加载到的是哪一份凭据,而不是你以为它该加载哪一份。
- 若是 403 或 404:固定凭据不动,只换模型 ID。结果会告诉你这是权限问题还是拼写问题。
- 若是 400:把错误文本读完,它会点名是哪个参数或哪项组织设置。
- 以上都做完之后,再考虑轮换 key——而且要用重叠窗口而不是硬切换,方法见 API key 轮换实践。
常见问题
为什么控制台里能用的 key,调接口却返回 401?
控制台并不使用你的 API key,它认证的是你的浏览器会话。一把从未真正跑过 HTTP 请求的 key,可能已被吊销、被打错、或被放进了错误的请求头,而控制台完全看不出差别。先查请求头名称,再查是不是同时还设了第二个凭据变量。
403 是不是意味着 key 无效?
不是。403 表示凭据认证成功之后,被拒绝执行某个具体动作——通常是访问某个模型、某个工作区或某个 beta 功能。key 本身是有效的,重新生成不会改变结果。
为什么我跑了一次命令行登录之后请求反而开始失败?
大概率不是登录导致的。检查环境里是否还导出着一把旧 key,因为环境变量的优先级高于你刚创建的那个配置档。在断定「登录坏了」之前,先确认当前生效的是哪个来源。
404 是不是表示我的 key 没有该模型的权限?
不是,那种情况会返回 403。404 表示按你写的那个字符串,模型 ID 或接口路径根本不存在。检查是不是把连字符写成了点,或者给一个不带日期后缀的模型 ID 硬加了日期后缀。
余额或计费问题会不会看起来像 key 失效?
看起来可能像,但它不会以 401 的形式出现。额度不足或计费受限会表现为一个请求级错误,信息里会点明这个状况,所以要读错误文本,而不是先入为主地当成认证问题。想了解余额这一侧怎么运作,见 Claude API 额度充值。
不写代码怎么测一把 key?
向消息接口发一个最小请求,带三个头——key 放在 x-api-key、anthropic-version 设为文档给出的版本串、content-type 设为 JSON——请求体里只放一个模型名和一句话。它要么返回内容,要么返回一个错误对象,把你定位到上面那张表里。测试时别加任何多余的东西,额外参数可能引出一个 400,反而盖掉你要找的答案。
一句话总结
先读状态码,再动 key。只有 401 才指向凭据,而即便落在 401 里,高频成因也是请求头放错或同时设了两个凭据变量,而不是 key 本身坏了。403 是认证通过但没权限,404 是模型 ID 拼错,400 是请求体或组织设置,429 则说明 key 工作得很好。当一把有效的 key 看起来被无视时,答案几乎总是凭据解析顺序——链条上更靠前的某一项赢了,而一条状态命令就能告诉你是哪一项。