所有文章
AI

Codex token exchange failed 报 403 怎么办?5 个有效修法,附实测

Codex 登录报 Token exchange failed,多半是 Codex 进程自己发给 auth.openai.com 的请求没走代理,或者根本没连上。本文分清 403 和 error sending request 两种情况,依据 openai/codex 的 GitHub issue 和我们用 codex-cli 0.165.0 的实测。

Codex token exchange failed:浅蓝色黏土小亭子,小票卡在关着的卷帘窗下,旁边的窗口开着,绿色小路牌指着方向

浏览器里已经登录成功、页面也提示可以回到终端了,Codex 却报 codex token exchange failed(Token exchange failed),十有八九是 Codex 进程自己发出去的那一个请求没走代理。在国内遇到的大多是带 403 的这一种:Token exchange failed: token endpoint returned status 403 Forbidden。下面按报错原文分开讲原因和修法,依据是 openai/codex 仓库的 GitHub issue、Codex 官方登录文档,以及我们在一台 Linux 测试机上用 codex-cli 0.165.0 跑出来的结果。

codex token exchange failed 是哪一步出错

Codex 用 ChatGPT 账号登录分两步。第一步在浏览器里完成:你登录、授权,浏览器把一个一次性的授权码交回本机 1455 端口上的 Codex。第二步由 Codex 进程自己完成:它拿这个授权码去请求 https://auth.openai.com/oauth/token,换回真正的登录凭据。报 codex token exchange failed,就是第二步出了问题。

所以浏览器那边顺利,不代表第二步也能通。浏览器用的是浏览器或系统的代理设置,Codex 进程用的是它自己读到的环境变量。我们在测试机上运行 codex doctor,网络一栏写着 respect system proxy disabled,也就是默认不读系统代理。在 openai/codex 源码里,respect_system_proxy 这个开关目前还标着开发中、默认关闭;源码里换 token 的那段逻辑只在连接失败时才会改用系统代理重试,服务器返回 403 时不会重试。最后这一点是我们读源码得出的判断,不是官方文档的说法。

常见的报错有两种写法:

Token exchange failed: token endpoint returned status 403 Forbidden
Token exchange failed: error sending request for url (https://auth.openai.com/oauth/token)

前一种是请求到了服务器、被拒了;后一种是请求根本没发出去。两种的修法不一样。

报 403 Forbidden:请求从不支持的地区直接发出去了

openai/codex issue #10466 就是这个报错,2026 年 2 月开的,到现在还没关。下面的回复里,能解决问题的办法几乎都和代理有关。用户 aweng126 在 2026 年 9 月的回复里总结得比较清楚:换 token 这一步是 Codex 进程自己发的,它只读 https_proxy、http_proxy、all_proxy 这几个环境变量(大小写都行),不管浏览器和系统代理;进程里没有这些变量,请求就从你的真实 IP 直接出去,然后拿到 403。

这和 OpenAI 的地区限制对得上。OpenAI 的支持国家和地区列表里没有中国大陆,从不支持的地区访问 API 会返回 403,详见OpenAI 403 Country, region, or territory not supported 的说明。我们的测试机在美国,用一个无效授权码直接请求 https://auth.openai.com/oauth/token,返回的是 401 和 token_expired,不是 403。也就是说,请求从支持的地区到达服务器时,授权码不对会得到 401;看到 403,更可能是出口 IP 或网络策略被拒。这是推断,OpenAI 没有公开说明这个接口返回 403 的条件。

所以在国内遇到 403 版的 codex token exchange failed,修法是在同一个终端里先设好代理变量,再运行 codex login:

export https_proxy=http://127.0.0.1:你的代理端口
export http_proxy=http://127.0.0.1:你的代理端口
export no_proxy=127.0.0.1,localhost,::1
codex login

no_proxy 这一行不能省。浏览器要把授权码交回 localhost:1455,这段本机通信如果也被送进代理,回调会失败。issue #10466 里 UnCrownGod 在 Ubuntu 加 Clash Verge 的环境下,就是靠 NO_PROXY=127.0.0.1,localhost,::1 加上 HTTP 代理端口解决的。端口要填代理工具的 HTTP 端口或混合端口,具体是多少看你自己的代理软件设置。

如果用的是 VS Code 插件或 Codex 桌面版,变量必须在程序启动之前就存在。在已经打开的程序外面 export 没有用,要关掉程序,从设好变量的终端重新启动。issue #50994 里有 Windows 用户反映 Codex 桌面版不走代理,回复的用户 afukuda1111 也是带着 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 启动程序才绕过去的。

SOCKS 代理要写 socks5://

issue #10466 里还有一个容易被忽略的点:chenzhaoqiJM 把 all_proxy 从 socks:// 改成 socks5://127.0.0.1:7897 后,403 就没了。我们在测试机上验证了原因。127.0.0.1:7897 上没有任何程序监听,分别设两种写法运行 codex login --device-auth:

  • all_proxy=socks5://127.0.0.1:7897:报 error sending request for url (https://auth.openai.com/api/accounts/deviceauth/usercode),说明 Codex 确实在用这个代理。
  • all_proxy=socks://127.0.0.1:7897:没有报错,直接显示了设备码。代理端口是空的还能成功,说明这个变量被忽略了,请求是直连出去的。

在国内,被忽略的结果就是直连,直连就是 403。所以 SOCKS 代理一律写 socks5://,或者干脆改用 HTTP 端口。

报 error sending request:代理端口、证书和远程机器

error sending request for url (https://auth.openai.com/oauth/token) 对应 issue #26764,有 25 条回复。和 403 相反,这种 codex token exchange failed 是请求连出去都没成功。回复里查出来的原因主要有这几类:

  • 代理端口过期。有人的 HTTP_PROXY 还是 127.0.0.1:6850,代理软件早就换成了 7892;还有人在 macOS 上把旧端口写在了 ~/.codex/.env 里。Codex 启动时会读这个文件,改了代理端口却忘了它,就会一直失败。
  • SSL_CERT_FILE 指向一个已经不存在或不对的证书文件。官方文档说 Codex 可以用 CODEX_CA_CERTIFICATE 指定自定义 CA 证书,不设时会退回读 SSL_CERT_FILE。公司网络做了 HTTPS 解密的,按文档配置公司 CA。
  • 在远程机器上登录。用 VS Code Remote SSH 时,浏览器在你本机,Codex 在服务器上,回调到不了服务器。官方文档给的办法是用 ssh -L 1455:localhost:1455 把端口转发过去,或者用设备码登录。
  • 版本太旧。有 WSL 用户把插件自带的 CLI 从 0.142 升到 0.144.5 后恢复了。
  • 被 Cloudflare 拦截。issue #16052 里一位澳大利亚用户的 CLI 换 token 时遇到了 Cloudflare 验证,这种情况换网络或换出口通常比改配置有效。

我们复现了第一种 codex token exchange failed。在测试机的 ~/.codex/.env(我们的 CODEX_HOME 指向测试目录)里写一个没人监听的代理端口,再运行 codex doctor 和 codex login --device-auth:

codex token exchange failed 实测:~/.codex/.env 里写了过期代理端口时 codex doctor 和 codex login --device-auth 的真实输出

codex doctor 列出了从 .env 读到的 HTTP_PROXY, HTTPS_PROXY,WebSocket 握手报 Connection refused (os error 111),可达性检查判定 ChatGPT 的接口连不上。设备码登录也失败,报 error sending request for url。删掉这个文件再跑,codex doctor 显示 no proxy env vars、接口可达,设备码登录正常显示了验证码。

按这个顺序排查

codex token exchange failed 修法对照表:403 Forbidden、error sending request、socks:// 被忽略、SSL_CERT_FILE、远程 SSH
  • 先看完整报错,分清是 403 还是 error sending request。
  • 运行 codex doctor,看 Connectivity 部分:读到了哪些代理变量,reachability 是不是 ✓。这是 Codex 进程的视角,比浏览器能打开网站更有参考价值。
  • 检查 ~/.codex/.env 和 shell 配置文件里有没有过期的代理端口或 SSL_CERT_FILE。
  • 在同一个终端里 export https_proxy、http_proxy、no_proxy,SOCKS 写成 socks5://,然后 codex login。
  • 本机回调总是失败,就换 codex login --device-auth。官方文档说这个方式还在 beta,需要先在 ChatGPT 的安全设置里开启设备码登录。它不需要 1455 端口回调,但换 token 的请求照样由 Codex 发出,代理变量仍然要设。
  • 失败后看 ~/.codex/log/codex-login.log,官方文档说登录过程的日志在这里。
  • 用 codex login status 确认登录状态。
  • 实在登不上,官方文档还允许在能登录的机器上完成登录,再把 ~/.codex/auth.json 复制到目标机器。这个文件等于你的登录凭据,不要发给别人,也不要传到公开仓库。

issue #26764 里有人删掉整个 ~/.codex 目录后好了。我们不建议一上来就这么做,里面有你的配置和会话记录;按上面查清楚原因,通常只需要改一两个变量。

如果你根本不需要用 ChatGPT 账号,也可以改用 API key:codex login --with-api-key。不过 API 同样受地区限制,代理问题不会因此消失。API key 报 401 时看OpenAI 401 Incorrect API key provided 的修法。

常见问题

codex token exchange failed 是账号被封了吗?

多数情况不是。issue #10466 和 #26764 里能解决的案例,改的都是代理、证书或端口,账号本身没动。

浏览器能打开 ChatGPT,为什么 Codex 还是报 codex token exchange failed 403?

浏览器和 Codex 走的不是同一套代理设置。Codex 默认只读环境变量,codex doctor 里的 respect system proxy disabled 说的就是这个。

开了 TUN 模式还会报吗?

TUN 模式接管的是整台机器的流量,一般不依赖环境变量。如果开着 TUN 还报 403,就要看出口节点所在的地区是否在 OpenAI 支持列表里。我们没有在 TUN 模式下实测,这一条是根据原理推断的。

解决了 codex token exchange failed 之后,Codex 的其他报错可以查OpenAI Codex 报错速查表。还没装好 Codex 的,先看Codex CLI 安装和登录教程。

留下你的想法

你的邮箱不会公开。