UnitySVC

API Key 401 Unauthorized 错误排查指南

更新于 2026-10-23 · unitysvc.cyou

简答:API Key 遇到 401 Unauthorized,优先检查三件事:请求是否真的带上了认证信息、Key 是否完整有效、Base URL 和认证方式是否与服务商文档匹配。最快的定位方法是先用带 <code>-i</code> 的最小 curl 请求验证,再对比 SDK 或工具实际发送的请求;如果 curl 成功而程序失败,问题通常在环境变量、配置覆盖、缓存或代理转发链路。

定义:401 Unauthorized 表示服务器没有收到可用于认证的有效凭据;它通常不是模型参数错误,而是 API Key 缺失、无效、格式错误、未生效或被中间层丢弃。

先试这一步:用最小请求判断 Key 还是客户端配置

本站为第三方指南,非 UnitySVC 官方,以其官网为准。下面的命令只用于定位通用的 API 鉴权问题;请把 https://api.example.com/v1 替换为目标服务商文档规定的 Base URL,并确认该服务支持列出模型的端点。

最小请求与结果判断
环境命令如何判断
Bash、macOS、Linuxcurl -i "$BASE_URL/models" -H "Authorization: Bearer $API_KEY"重点看 HTTP 状态、响应正文、WWW-Authenticate、request ID 等响应头
PowerShellcurl.exe -i "$env:BASE_URL/models" -H "Authorization: Bearer $env:API_KEY"使用 curl.exe,避免 PowerShell 对 curl 命令的别名行为造成差异
服务商要求专用请求头curl -i "$BASE_URL/models" -H "X-API-Key: $API_KEY"不要把 Bearer 写法套用到明确要求其他 Header 的服务

OpenAI API 的官方示例使用 Authorization: Bearer OPENAI_API_KEY,并以 /v1/models 作为可验证的请求路径;兼容接口可能拥有不同的路径、Header 或模型端点,应以对应文档为准。可参考 API 鉴权文档。

如果最小请求本身返回 401,先不要改 SDK 参数,继续检查 Key、Header 和 Base URL。如果最小请求成功,但 Postman、脚本或客户端仍返回 401,则问题位于本地配置生效链路或代理层。

按证据链排查 401:请求、凭据、地址、转发四层

  1. 先读响应正文和响应头。记录错误类型、错误消息、WWW-Authenticate、request-id 或服务商提供的请求编号。HTTP 规范语义中的 401 是未完成有效认证,服务器通常会通过 WWW-Authenticate 提示可接受的认证方案,可参考 MDN 对 401 的说明。
  2. 确认使用的是 API Key。网页登录密码、Cookie、浏览器会话、项目名称或控制台 URL 都不能自动替代 API Key。不要把完整 Key 粘贴到日志、截图、工单或聊天记录中。
  3. 检查 Key 是否被破坏。重点看复制时是否带了前后空格、换行、额外引号或不可见字符;同时确认 Key 未过期、未撤销,并且属于当前 API 项目或组织。具体有效期和撤销规则必须以服务商控制台和文档为准。
  4. 核对认证格式。常见格式是 Authorization: Bearer <API_KEY>,但部分网关使用 X-API-Key 或其他专用 Header。不要同时发送多个互相冲突的认证 Header。
  5. 核对 Base URL 和路径。常见错误包括把控制台地址当 API 地址、重复拼接 /v1、漏掉必要的版本前缀、把 Anthropic 风格路径发给 OpenAI 兼容端点,或使用了不支持该资源的域名。Base URL 不匹配时,错误可能表现为 401、404 或网关自定义错误,不能只看状态码。
  6. 排查代理和网关。如果本机直接请求成功,但经过反向代理、API Router、公司网关或自建服务后变成 401,检查代理是否允许并转发 Authorization,是否发生了重定向,以及是否把 Header 改写为空。用代理前后的 -i 响应头、网关访问日志和 request ID 对照确认。

Postman 官方建议检查 URL、Authorization 类型、凭据,并通过 Postman Console 查看实际发送的请求头、变量值和重定向;可参考 Postman 的 401 排查说明。

Key 看似存在但仍然 401:检查环境变量和配置覆盖

程序中写了 API_KEY 不代表运行时真的读到了它。常见情况是:在一个终端设置变量,却在另一个终端启动程序;PowerShell 变量只对当前会话生效;IDE、Docker、CI 或服务管理器覆盖了本地变量;项目根目录的 .env 没有被加载;或者旧进程仍在使用缓存配置。

Bash 中只检查变量是否存在,不打印完整 Key:

test -n "$API_KEY" && echo "API_KEY is set" || echo "API_KEY is missing"
printf 'API_KEY length: %s\n' "${#API_KEY}"
printf 'BASE_URL=%s\n' "$BASE_URL"

PowerShell 中:

if ([string]::IsNullOrEmpty($env:API_KEY)) { "API_KEY is missing" } else { "API_KEY is set" }
if ($env:API_KEY) { "API_KEY length: $($env:API_KEY.Length)" }
$env:BASE_URL

不要把 Key 写入源代码或提交到 Git。OpenAI 官方文档建议把 Key 放在环境变量或密钥管理服务中,官方 Python SDK 也展示了通过 OPENAI_API_KEY 读取凭据的方式,可参考 官方鉴权文档 和 官方 Python SDK 文档。使用 .env 时,应将其加入忽略规则,并确认负责加载它的库或启动脚本确实执行。

如果你刚修改了变量,重新启动当前终端、IDE、开发服务器、容器或后台进程,再做一次最小请求。不要通过打印完整变量值来验证,以免密钥进入终端历史或日志。

curl 成功但 JavaScript、Python 或 SDK 失败怎么办

此时不要立即更换 Key,先把成功的 curl 与失败程序做逐项对照:请求 URL、HTTP 方法、Authorization Header、Content-Type、重定向、代理和实际使用的模型或资源路径。只要其中一项不同,就不能说明两次请求等价。

JavaScript:显式确认运行时配置

const key = process.env.API_KEY;
if (!key) throw new Error('API_KEY is missing');
const response = await fetch(`${process.env.BASE_URL}/models`, {
headers: { Authorization: `Bearer ${key}` }
});
console.log(response.status, await response.text());

不要把服务端 Key 放到浏览器前端。官方 JavaScript SDK 默认从 OPENAI_API_KEY 读取 Key,也支持通过 OPENAI_BASE_URL 配置兼容端点;相关配置见 官方 JavaScript SDK 鉴权文档。

Python:区分变量缺失与服务端拒绝

import os
import requests

key = os.environ.get("API_KEY")
base_url = os.environ.get("BASE_URL")
if not key:
raise RuntimeError("API_KEY is missing")
r = requests.get(f"{base_url}/models", headers={"Authorization": f"Bearer {key}"}, timeout=30)
print(r.status_code, r.text)

如果直接请求成功、SDK 失败,检查 SDK 的 api_key、base_url 或对应环境变量是否被显式参数覆盖。官方 Python SDK 文档说明客户端可以从环境变量读取 Key,也可以传入自定义的 Base URL,详见 官方 Python SDK README。

401、403、404、429、402 和 400 怎么区分

API 常见状态码的第一检查方向
状态或错误通常先检查什么不要误判成什么
401 UnauthorizedKey 是否缺失、无效、格式错误;Authorization 是否被发送或被代理剥离不要先把问题归因于模型参数
403 Forbidden凭据已被识别后,检查项目权限、资源权限、来源限制或策略与 401 的“未认证”不同
404 Not FoundBase URL、版本前缀、资源路径和模型名称可能是端点不存在,不一定是 Key 错误
429 Too Many Requests限速、并发、重试策略和配额不要反复更换 Key 作为第一反应
402 Payment Required 或 billing 错误账户余额、计费状态、项目额度及服务商规则402 的具体含义并非所有 API 都统一
400 Bad RequestJSON、HTTP 方法、必填字段、请求头和参数格式不要把参数错误当作鉴权失败
unsupported_parameter检查参数名是否被当前模型或端点支持,删除不兼容字段通常不是 API Key 失效

HTTP 状态码的通用定义可参考 MDN HTTP 状态码参考;具体服务仍可能返回自定义错误类型,因此最终应以该服务的错误文档和响应正文为准。

一份不泄露密钥的 401 自查清单

常见问题

API Key 401 Unauthorized 最常见的原因是什么?

最常见方向包括 Key 没有发送、Authorization 格式错误、Key 复制时带了空格或换行、Key 已撤销或过期,以及 Base URL 与 Key 所属服务不匹配。先用 <code>curl -i</code> 发最小请求,能快速区分服务端凭据问题与 SDK 配置问题。

Authorization 应该写成什么格式?

许多 OpenAI 兼容接口使用 <code>Authorization: Bearer <API_KEY></code>,但不是所有服务都相同。若服务商文档要求 <code>X-API-Key</code> 或其他 Header,应按其规定发送,不要同时添加互相冲突的认证字段。

环境变量明明设置了,为什么程序仍然返回 401?

可能是在不同终端设置了变量,PowerShell 会话已经结束,IDE 或容器没有继承变量,<code>.env</code> 没有被加载,或者 SDK 的显式参数覆盖了环境变量。只检查变量是否存在和长度,不要打印完整 Key;修改后重启实际运行程序的进程。

curl 成功但 Postman 或 SDK 失败,应该怎么办?

把两次请求的 URL、路径、认证 Header、重定向、代理和请求体逐项对比。Postman 可打开 Console 查看实际发送的请求头、变量值和重定向;SDK 则重点检查 <code>api_key</code>、<code>base_url</code> 和对应环境变量是否生效。

401 和 403 有什么区别?

401 通常表示服务器没有收到有效认证凭据;403 通常表示凭据已被识别,但当前身份没有访问该资源或执行该操作的权限。实际服务可能使用自定义错误,因此还要结合响应正文和服务商文档判断。

代理或网关会导致 API Key 变成 401 吗?

会。若直连 API 成功、经过反向代理或网关后变成 401,应检查代理是否转发 <code>Authorization</code>、是否发生重定向、是否改写了 Header,以及后端日志中是否实际收到请求。

相关阅读

参考资料

  1. OpenAI API 鉴权与请求调试文档
  2. MDN:401 Unauthorized
  3. MDN:HTTP 状态码参考
  4. Postman:Fixing a 401 Unauthorized response error(support.postman.com)
  5. OpenAI 官方 Python SDK README
  6. OpenAI 官方 JavaScript SDK 鉴权文档
  7. github.com