☰
Codex 401 unauthorized 报错排查指南:从环境变量到 base_url 的完整定位流程
2026/9/26 5:16:03 网站建设 项目流程

1. 401 报错到底卡在哪一环:先分清是"没带钥匙"还是"钥匙不对"

Codex 报401 unauthorized这件事,我前后帮人排查过不下二十次,发现一个规律:绝大多数人一看到 401 就本能地去重新登录、重新生成密钥,折腾半天还是报错,最后发现根本不是密钥的问题。所以这篇我打算把整个排查链路拆开讲,从报错文本的细微差别入手,一步步定位到真正的原因,而不是让你盲目试错。

先说清楚 Codex 在这里指什么。它是 OpenAI 推出的一套命令行编程助手工具(Codex CLI),可以跑在终端里,也可以作为插件集成到 VS Code 这类编辑器里。它的工作方式是:你在本地敲命令,它把请求发到远端模型接口,拿到结果再返回给你。而401 unauthorized这个状态码,在 HTTP 语义里非常明确——服务器认为你没有通过身份认证。注意,是"认证"(authentication)失败,不是"授权"(authorization)不足,后者通常是 403。这个区别很关键,它把问题范围直接缩小到了"身份凭证"这一层。

但"身份凭证"这四个字背后其实有好几种可能:凭证压根没传、传了但格式不对、传了但内容无效、传了但发给了错误的地址、或者凭证本身权限不够。这五种情况在 Codex 里都会表现为 401,但报错文本的细节完全不同。我整理了一张对照表,你可以先对着自己的报错信息定位:

报错文本关键片段真实含义大概率原因
missing bearer or basic authentication请求里根本没带认证头环境变量没设置,或配置文件没被读取
api_key_required服务端要求提供密钥但没收到密钥变量名为空或拼写错误
invalid_api_key密钥格式对但服务端不认密钥失效、复制错误、或用了别家的密钥
incorrect api key provided: sk-xxx****密钥内容错误密钥被截断、含多余空格、或已撤销
insufficient permissions密钥有效但权限不足账号套餐、组织权限或模型访问权限问题
auth token is unavailable本地缓存的登录态丢失登录会话过期,需要重新登录

这张表是我踩坑踩出来的经验总结,不是官方文档抄的。你只要把报错原文往里一套,基本就能锁定方向。下面几节我会按"从最常见到最隐蔽"的顺序,把每一类问题的排查和修复讲透。

提示:排查前先把完整报错原文复制下来,别只看最后一行。Codex 的报错经常是多层嵌套的,最外层是unexpected status 401,里面还包着一层 JSON,真正的线索往往在内层。

2. 环境变量这条线:OPENAI_API_KEY 为什么设了还是没用

2.1 变量名拼错和大小写问题,比你想的更常见

我遇到最多的一个情况,就是用户信誓旦旦说"我明明设了环境变量",结果一查,变量名写成了OPEN_AI_API_KEY或者OPENAI_APIKEY。Codex 读取的是OPENAI_API_KEY,一个下划线都不能差,大小写也必须完全一致。在 Linux 和 macOS 上,环境变量是区分大小写的,openai_api_key和OPENAI_API_KEY是两个完全不同的变量。

验证方法很简单,在终端里敲:

# Linux / macOS echo $OPENAI_API_KEY # Windows PowerShell echo $env:OPENAI_API_KEY # Windows CMD echo %OPENAI_API_KEY%

如果输出是空的,那问题就找到了。如果输出了一串sk-开头的字符,说明变量设对了,继续往下查。

2.2 设了变量但当前终端读不到:会话隔离的坑

这是第二个高频坑。很多人在.bashrc或.zshrc里加了export OPENAI_API_KEY=sk-xxx,然后直接在已经打开的终端里跑 Codex,结果还是 401。原因是:修改配置文件不会影响已经打开的终端会话。你必须新开一个终端窗口,或者手动执行source ~/.zshrc让配置生效。

Windows 上更麻烦一点。如果你是用图形界面"系统属性 → 环境变量"设置的,那么已经打开的 CMD 或 PowerShell 窗口同样读不到新值,必须关掉重开。而且 Windows 分"用户变量"和"系统变量",如果你在用户变量里设了,但 Codex 是以管理员身份运行的,那它读的是系统变量,两者不互通。

我个人的习惯是,排查阶段直接在启动 Codex 的同一个终端里临时 export 一次,确认能通之后再写进配置文件:

export OPENAI_API_KEY="sk-你的密钥" codex

这样能快速区分"是变量没生效"还是"是密钥本身有问题"。

2.3 密钥里的隐形字符:复制粘贴的陷阱

从网页上复制密钥的时候,很容易带上首尾的空格、换行符,甚至是一些不可见的 Unicode 字符。这些字符在终端里看不出来,但会让服务端认为密钥无效,返回incorrect api key provided。

判断方法:把密钥用引号包起来 echo 一下,看长度对不对。正常的密钥长度是固定的,如果你 echo 出来的字符数比预期多,那多半混进了杂质。更稳妥的做法是用cat -A查看隐藏字符:

echo -n "$OPENAI_API_KEY" | cat -A

如果行尾出现了^M或者$之外的东西,就说明有问题。修复方式就是重新复制,或者手动把密钥写进配置文件而不是靠粘贴。

注意:密钥一旦泄露(比如贴到了公开的聊天记录、截图、代码仓库里),要立刻去后台撤销并重新生成。401 有时候反而是好事,说明泄露的密钥已经被系统判定失效了。

3. codex login 与 API Key 两套认证机制,别混着用

3.1 登录态认证和密钥认证是两条独立的路

Codex 支持两种认证方式:一种是通过codex login走账号登录,凭证会缓存在本地;另一种是直接配置 API Key。这两套机制是互相独立的,但很多人会把它们搞混,导致认证冲突。

如果你用的是codex login登录,那么凭证存在本地的配置目录里(通常是用户主目录下的隐藏文件夹)。这种情况下,即使你没有设置OPENAI_API_KEY,也应该能正常使用。反过来,如果你设置了 API Key,但本地还残留着过期的登录态,有时候反而会互相干扰。

排查登录态问题,可以这样操作:

# 查看当前登录状态 codex auth status # 如果显示未登录或已过期,重新登录 codex login # 退出登录,清掉本地缓存 codex logout

我遇到过一种情况:用户之前登录过,后来账号换了,但本地缓存没清,结果一直报auth token is unavailable。解决办法就是先logout再login,把旧凭证彻底清掉。

3.2 什么时候该用登录,什么时候该用密钥

这里给个我自己的判断标准。如果你只是个人使用、图省事,用codex login最方便,它会自动处理凭证刷新。但如果你需要在 CI/CD 流水线里跑、或者要在多台机器上统一配置、又或者要接入第三方兼容接口,那就必须用 API Key,因为登录态没法在无头环境里维持。

还有一个细节:有些第三方兼容服务(比如把 Codex 指向别的模型接口)只认 API Key,不认登录态。这种情况下你就算登录了也没用,必须老老实实配密钥。

3.3 登录后仍报 401 的排查顺序

如果你确认已经登录,但还是 401,按这个顺序查:

  1. 先codex auth status看登录态是否有效
  2. 检查是否有残留的OPENAI_API_KEY环境变量在"抢戏",如果有,先 unset 掉
  3. 检查配置文件里是否同时存在登录凭证和密钥配置,两者冲突时以哪个为准要看具体版本
  4. 确认账号本身没有被限制或欠费
# 临时清掉环境变量,测试纯登录态能否工作 unset OPENAI_API_KEY codex

这一步能帮你快速判断问题出在登录态还是密钥上。

4. 接入第三方兼容接口:base_url 配错是最隐蔽的 401

4.1 为什么改了 base_url 反而报 401

现在很多人会把 Codex 指向第三方兼容接口来用,比如把codex_base_url设成某个兼容 OpenAI 协议的服务地址。这时候 401 的成因就多了一层:你用的密钥是 A 家的,但请求发给了 B 家。B 家当然不认 A 家的密钥,直接返回 401。

热词里出现的set codex_base_url=https://api.deepseek.com/v1和set openai_api_key=sk-xxx就是典型场景。如果你把 base_url 指向了 DeepSeek 的接口,那OPENAI_API_KEY里就必须填 DeepSeek 的密钥,而不是 OpenAI 的密钥。这两者不通用。

排查方法:确认你的 base_url 和密钥是同一家的。可以先用 curl 单独测一下:

curl https://api.deepseek.com/v1/models \ -H "Authorization: Bearer sk-你的密钥"

如果这个 curl 返回 401,说明密钥和地址不匹配,或者密钥本身无效。如果 curl 能通但 Codex 报 401,那问题就在 Codex 的配置读取上。

4.2 base_url 的路径细节:结尾的 /v1 不能少也不能多

兼容接口的 base_url 对路径很敏感。有的服务要求结尾带/v1,有的要求不带,有的甚至要求带完整的/v1/chat/completions。配错了路径,请求会打到错误的端点,返回的可能是 404,也可能是 401(取决于服务端的处理逻辑)。

我建议的做法是:先查清楚目标服务的文档,确认它要求的 base_url 格式,然后严格照抄。不要凭感觉加或减/v1。配置完之后,用codex发一个最简单的请求测试,看报错是 401 还是 404,能帮你区分是认证问题还是路径问题。

4.3 代理转发场景下的认证头丢失

热词里有个cc switch local proxy failed while handling codex endpoint /responses,这说的是通过本地代理转发请求的场景。这种架构下,401 的一个常见原因是:代理在转发时把认证头弄丢了。

请求链路是:Codex → 本地代理 → 目标服务。如果代理没有正确透传Authorization头,目标服务收到的就是无认证请求,返回missing bearer or basic authentication。排查这种问题,要在代理层加日志,确认转发出去的请求里到底有没有认证头。

提示:如果你用的是本地代理方案,先在代理配置里打开请求日志,把转发前后的 header 都打出来对比。这一步能省掉大量猜测时间。

5. 从报错文本反推根因:一套可复用的排查流程

5.1 第一步永远是拿到完整报错

很多人排查效率低,就是因为只看了一眼"401"就开始瞎试。正确的第一步是把完整报错复制出来,逐字读。Codex 的报错通常长这样:

unexpected status 401 unauthorized: {"code":"invalid_api_key","message":"Incorrect API key provided: sk-xxx****"}

这里面invalid_api_key和Incorrect API key provided就是金线索。前者告诉你密钥无效,后者告诉你密钥内容错了。对照第 1 节的表格,直接定位到"密钥内容错误"这一类。

5.2 第二步:用最小化测试隔离变量

定位到大致方向后,别急着改 Codex 的配置,先用 curl 做最小化测试。curl 排除了 Codex 本身的所有干扰,能直接告诉你"密钥 + 地址"这个组合到底通不通。

# 测试密钥和地址是否匹配 curl -s -o /dev/null -w "%{http_code}" \ https://api.openai.com/v1/models \ -H "Authorization: Bearer $OPENAI_API_KEY"

返回 200 说明密钥和地址没问题,问题在 Codex 配置;返回 401 说明密钥或地址有问题,继续查这两个。

5.3 第三步:逐层排除配置来源

Codex 读取配置的来源可能有多个:环境变量、配置文件、命令行参数。这三者的优先级在不同版本里可能不一样。排查时要把所有来源都列出来,确认最终生效的是哪一个。

# 查看所有可能相关的环境变量 env | grep -i -E "openai|codex|api_key" # 查看配置文件位置(具体路径以你的版本为准) ls -la ~/.codex/ 2>/dev/null ls -la ~/.config/codex/ 2>/dev/null

把环境变量和配置文件里的值都拿出来对比,看有没有冲突。我遇到过环境变量里是旧密钥、配置文件里是新密钥的情况,结果 Codex 读了环境变量,一直报 401。

5.4 第四步:确认账号和权限状态

如果密钥格式、地址、配置来源都排查过了还是 401,那就要怀疑账号本身了。可能的情况包括:账号欠费、密钥被撤销、组织权限变更、或者访问的模型不在你的套餐范围内。热词里的you have insufficient permissions和the 'gpt-5.6-sol' model is not supported都属于这一类。

这时候要去服务商的后台确认账号状态和密钥状态,而不是在本地继续折腾。

6. 几个容易被忽略的细节和我的实操心得

6.1 版本不匹配导致的认证协议变化

Codex 更新比较频繁,不同版本对认证的处理方式可能有变化。我遇到过升级之后旧配置失效的情况。如果你是在升级后突然开始报 401,第一件事就是去看更新日志,确认认证相关的配置有没有变更。有时候重新跑一次codex login或者重新生成配置文件就能解决。

6.2 多环境共存时的配置污染

如果你同时在用多个 AI 编程工具,它们可能都读OPENAI_API_KEY这个变量。这时候一个工具的配置可能会影响另一个。我的做法是给每个工具用独立的配置文件,而不是全靠全局环境变量。这样能避免"改了 A 结果 B 坏了"的情况。

6.3 网络环境对认证的影响

有些网络环境下,请求会被中间设备拦截或改写,导致认证头丢失或损坏。如果你在某个特定网络下必现 401,换个网络就正常,那基本可以确定是网络链路的问题。这种情况下,检查本地的网络配置和代理设置,确认请求是直连还是经过了中间层。

6.4 我的排查口诀

最后分享一个我自己总结的排查口诀,按这个顺序走,九成以上的 401 都能定位:

  1. 看报错:完整读一遍,对照表格定位类别
  2. 查变量:确认变量名、值、生效范围都对
  3. 测连通:用 curl 隔离 Codex,测密钥和地址
  4. 对来源:环境变量、配置文件、命令行参数逐个核对
  5. 验账号:确认账号和密钥在服务端的状态正常
  6. 换环境:排除网络和版本因素

这套流程的核心思路是从外到内、从简到繁,先用最简单的手段排除掉大部分可能,再逐步深入到复杂场景。盲目重装、盲目重新生成密钥,往往只是浪费时间,因为问题可能根本不在你以为的地方。

注意:每次只改一个变量,改完立刻测试。同时改多个地方,一旦问题解决你也不知道是哪个改动起的作用,下次遇到还是不会。

Codex 的 401 说到底就是"身份没对上"这一件事,但"对不上"的方式有十几种。把报错文本读透,把配置来源理清,把测试手段用对,这个问题其实一点都不难。我见过太多人卡在这里几个小时,最后发现只是变量名少了个下划线,或者密钥复制时多带了个空格。希望这篇能帮你少走点弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询