认证失败API Key / Authorization Header
401 Unauthorized:API 调用未通过认证怎么解决
请求已经发到 API 服务,但服务端没有接受你的身份凭证。优先检查 API Key、请求头、环境变量和 Base URL 是否属于同一个平台。
排查结论
先用最小请求隔离问题:只保留 API Key、Base URL、模型名和一条 ping 消息。最小请求失败,先修配置;最小请求成功,再回到业务代码排查并发、上下文和部署环境。
1. 问题现象
- HTTP 状态码返回 401,响应里出现 Unauthorized、invalid_api_key、Incorrect API key 或 authentication failed。
- 同一段代码昨天能跑,今天突然全部失败,通常是 Key 被删除、过期、轮换或账号权限变化。
- 控制台能正常登录,但 SDK、curl、Claude Code、Codex 或其他工具调用失败。
- 返回的是 HTML 登录页或网关错误页,而不是 JSON 错误对象,说明请求可能打到了错误地址。
2. 最可能原因
Authorization 请求头缺失,或没有使用 Bearer 前缀。
环境变量没有加载成功,代码实际传入的是空字符串、undefined 或旧 Key。
复制 API Key 时带了空格、换行、引号,或只复制了部分内容。
把 A 平台的 Key 用在 B 平台的 Base URL 上,例如 OpenAI Key 配了 DeepSeek Base URL。
Key 被删除、禁用、泄露后被轮换,或创建在另一个项目/组织下。
3. 快速排查清单
1
确认代码实际读到 Key
只打印长度和前后 4 位,不要打印完整 Key;长度为 0 或前缀不对时先修环境变量。
2
确认请求头格式
OpenAI 兼容接口通常是 Authorization: Bearer <API_KEY>;不要写成 Token、Basic 或只传裸 Key。
3
确认 Key 和 Base URL 属于同一平台
DeepSeek Key 配 https://api.deepseek.com,Kimi Key 配 https://api.moonshot.cn/v1,通义千问 Key 配 DashScope 兼容模式地址。
4
重新生成一个最小权限测试 Key
如果新 Key 可用,旧 Key 就是被删、过期、权限错误或复制错误。
5
用 curl 跳过业务代码测试
先用最小请求确认认证能通过,再回到 SDK 或工具配置。
4. 对应 API 的特殊情况
OpenAI
ChatGPT Plus/Pro 订阅不等于 API 额度。API Key 还要确认所属 Project、组织和 Billing 状态。
Claude / Anthropic
直连 Anthropic Messages API 使用 x-api-key 和 anthropic-version;不要把 Anthropic Key 当成 OpenAI Bearer Key 直接打 OpenAI 路径。
DeepSeek / Kimi / 通义千问
这些平台常用 OpenAI 兼容 SDK,但 base_url 必须换成各自平台地址,Key 也必须来自同一个平台控制台。
豆包火山方舟
model 经常是控制台里的推理接入点 ID;Key 正确但模型 ID 填错时也可能伴随认证或权限类错误。
5. 可复制的修复示例
用 curl 验证 Bearer Token 是否有效
bash
export API_KEY="sk-替换成你的真实Key"
export BASE_URL="https://api.deepseek.com"
curl -i "$BASE_URL/v1/models" \
-H "Authorization: Bearer $API_KEY"如果这里仍是 401,问题在 Key、Base URL 或账号权限,不在业务代码。
Python 中安全检查环境变量是否加载
python
import os
from openai import OpenAI
api_key = (os.getenv("DEEPSEEK_API_KEY") or "").strip()
if not api_key:
raise RuntimeError("DEEPSEEK_API_KEY 没有加载")
print("key_loaded", len(api_key), api_key[:4] + "..." + api_key[-4:])
client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com")
print(client.models.list().data[0].id)只打印脱敏信息,确认程序读到的是当前 Key。