# Codex 报错 Token Exchange Failed：先找失败阶段，再重新登录

> Codex 登录出现 token exchange failed 或 access token 无法刷新时，先区分授权码交换、后续刷新与远程本地回环回调，再按运行主机安全恢复。

- Source: https://www.aifreeapi.com/zh/posts/codex-access-token-could-not-be-refreshed
- Language: zh
- Published: 2026-08-25
- Updated: 2026-08-31
- Publisher: AI Free API (https://www.aifreeapi.com)

`Token exchange failed` 和 `Your access token could not be refreshed` 都属于 Codex 认证故障，但不是同一个阶段。前者通常出现在浏览器授权后、Codex 用授权码换取 token 时；后者发生在先前会话已经存在、进程尝试续期时。OpenAI 没有为这两条错误发布一张“错误文字等于唯一根因”的对照表，所以不要看到 token 就直接删缓存或归咎于代理。

浏览器显示“可以返回应用”也不代表交换已经完成：真正接收 callback、保存凭据并发起后续请求的是运行 Codex 的进程。更稳妥的做法是先回答三个问题：**哪一个 Codex 表面在报错、它实际运行在哪台主机、错误发生在浏览器回调之前还是已有会话刷新时。**

## 先用错误尾部判断故障边界

保留完整报错文字，但先脱敏。不同尾部指向不同的下一步：

| 可观察信号 | 当前能说明什么 | 先做什么 |
|---|---|---|
| `error sending request for url (.../oauth/token)`、连接或超时 | 运行 Codex 的进程没有完成到 token endpoint 的请求 | 在同一主机核对网络、代理与 TLS；不要只测试浏览器 |
| `token endpoint returned status 403` | 请求到达了端点，但被拒绝 | 记录状态与脱敏响应上下文，核对登录账号、工作区和受管策略；不要猜成“地区封锁” |
| 浏览器完成后 CLI 一直等 callback | 浏览器与 Codex 的本地回环回传路径可能没有闭合 | 先确认 CLI 是否在 WSL、SSH、容器或远端扩展宿主运行 |
| `access token could not be refreshed` | 已有会话续期失败 | 在真正执行的环境检查认证状态，再用受支持的 logout/login 重建凭据 |
| `CERTIFICATE_VERIFY_FAILED` 或明确 CA 错误 | 当前进程不信任连接所需的证书链 | 仅在已知企业 TLS 代理/私有根 CA 环境配置受信任证书包 |

这些信号用于缩小范围，不等于自动根因。尤其是 403：它证明“收到拒绝”，并不能仅凭一个状态码证明账号、地区、VPN 或订阅中的哪一项有问题。

![Codex token exchange failed 的中文分阶段诊断图，包含 exchange、callback、refresh、执行主机、设备码、SSH 回调、企业证书和恢复信号](https://www.aifreeapi.com/posts/zh/codex-access-token-could-not-be-refreshed/img/auth-failure-stage-map.webp)

## 先保住现场，再动登录状态

认证失败通常不会撤销已经写进仓库的改动。真正容易造成损失的，是在多个窗口里重复启动任务，或为了“清缓存”误删项目文件。

操作前先做这些事：

- 查看工作区里已经生成但尚未提交的改动；
- 保存尚未发送的提示词和经过脱敏的完整报错；
- 记下时间与时区、Codex 入口、版本、项目路径和最后一个成功动作；
- 停止在 App、CLI、IDE 里同时重复同一个任务。

不要把 `auth.json`、access token、refresh token、API Key、验证码、Cookie 或未脱敏的 HAR 发到群聊、Issue 或普通客服截图里。OpenAI 的[认证文档](https://learn.chatgpt.com/docs/auth#credential-storage)明确说明，文件型 `auth.json` 含有 access token，应当像密码一样保护。

## 你看到的界面，不一定是凭据所在的机器

最常见的误区是“我已经在电脑上退出了，为什么还报错”。因为界面在本机，不代表 Codex 进程也在本机。

| 使用方式 | 先确认的凭据边界 | 常见误判 |
|---|---|---|
| 本机 Codex App | App 当前账号或 API Key 状态、本机凭据存储 | 退出另一个浏览器里的 ChatGPT 就算清理完成 |
| 本机 Codex CLI | 当前 shell 的系统用户与 `CODEX_HOME` | 网页能正常打开就认为 CLI 凭据也正常 |
| VS Code／其他 IDE | 扩展宿主究竟在本地还是远程 | 只重装编辑器界面，没有处理远程扩展宿主 |
| WSL、SSH、容器、虚拟机 | 该环境内部的 home 目录或系统 keyring | 只在宿主机退出账号 |
| 第三方 Agent／Gateway | 它自己的认证 profile | 独立 CLI 能用，就认为所有工具都共享同一份登录 |

OpenAI 当前文档说明，Codex CLI 与 IDE 扩展可以共享缓存凭据；这些凭据可能在 `~/.codex/auth.json`，也可能在操作系统凭据存储里。这正是为什么不应把“手动删除 auth.json”当成第一步：文件可能不在你猜的位置，甚至根本没有文件。

![在真正运行 Codex 的主机上识别认证阶段、退出重登、选择远程登录方式并保护 token 等敏感信息的中文恢复路径](https://www.aifreeapi.com/posts/zh/codex-access-token-could-not-be-refreshed/img/recovery-path-and-secrets.webp)

## CLI 与 IDE：用支持的退出路径重建凭据

在**真正运行报错进程的环境**里，先查看当前认证方式：

```bash
codex login status
```

它可以告诉你凭据是否存在、当前采用哪种认证模式。如果你以为自己在使用 ChatGPT 方案，结果 shell 实际采用 API Key；或者 IDE 连接的是另一个 Linux 用户，这一步能立即暴露错位。

随后清理已经保存的 CLI 凭据并重新登录：

```bash
codex logout
codex login
```

在浏览器流程中选择你真正要使用的 ChatGPT 账号和工作区。完成后再次运行：

```bash
codex login status
```

OpenAI 的[认证文档](https://learn.chatgpt.com/docs/auth#check-authentication-or-sign-out)列出了 `codex login`、`codex logout` 和 `codex login status`；`codex logout` 用于清除当前存储的凭据。

如果报错来自 IDE，重新登录后要彻底关闭并重开 IDE，让旧的扩展宿主退出。CLI 和扩展可能共享缓存，但一个已经运行的扩展进程仍可能保留旧状态。

如果报错来自 Codex App，在 App 的个人资料菜单里确认当前账号或 API Key 状态，从 App 内退出，彻底关闭 App，再重新打开完成登录。只退出某个浏览器 profile 里的 `chatgpt.com`，不等于 App 的本地凭据已经被清除。

## 退出成功，重新登录却卡住了怎么办

一旦旧凭据已清理，而新登录在返回凭据之前失败，问题就已经变了。此时继续重复 logout 没有帮助，应按新登录失败的阶段处理。

远程或无界面的 CLI 可能无法让浏览器回调到运行 Codex 的本地回环端点。在账号或工作区允许的前提下，官方文档建议优先使用 beta 的 device code：

```bash
codex login --device-auth
```

打开命令给出的地址，登录后输入一次性 code。不要把 code 发给别人。若个人账号或企业工作区没有启用 device code，需要由账号设置或管理员侧处理。

如果仍要保留标准浏览器流程，且 CLI 在可 SSH 的远端运行，官方文档给出的默认 callback 是本地回环端口 1455。从本机建立转发后，在同一 SSH 会话执行登录：

```bash
ssh -L 1455:[::1]:1455 user@remote
codex login
```

不要在“CLI 实际本机运行”的情况下机械套用端口转发；也不要把 1455 暴露到公网。它只解决浏览器与远端 CLI 的本地回环 callback 路径，不解决 endpoint 403 或证书错误。

公司网络如果使用 TLS 解密代理或私有根证书，OpenAI 的认证文档提供了 `CODEX_CA_CERTIFICATE` 入口，用 PEM 证书包完成受信任连接。直接执行 `codex login` 还会在配置的日志目录写入专用 `codex-login.log`。它适合定位浏览器回调、证书或设备登录失败，但分享前必须删除 token、邮箱、工作区标识和敏感路径。

受管理的工作区可能强制使用 ChatGPT 或 API Key，也可能限定特定 ChatGPT workspace。新账号刚登录就被退出时，不要继续轮换本地文件；请管理员确认成员资格、provisioning、被允许的登录方式和目标工作区。

如果运行环境使用 workload identity，认证由进程环境和身份提供方控制。官方文档说明，这种情况下用户执行 `codex login` 或 `codex logout` 会被拒绝。修复入口应转到 federation 规则、运行时身份与管理员配置。

## 怎样才算真正恢复

“登录页面显示成功”还不够。一次可靠的恢复至少有三项证据：

1. `codex login status` 显示预期认证方式；
2. App 或 IDE 能看到正确账号、工作区或 API Key 状态；
3. 在原来报错的同一项目、同一运行环境里，一个小型低风险任务能够完成。

可以先让 Codex 只读总结一份不敏感的文件。不要立即恢复大型写入任务。小任务通过后，再检查仓库现有改动并继续原任务。

如果认证状态正确，但小任务返回 429，应转到 [Codex 限流归属排查](/zh/posts/codex-rate-limits)；如果卡在连接、工具或进程等待，应转到 [Codex 超时诊断](/zh/posts/codex-timeout)；如果新登录出现手机号、MFA 或设备验证，应使用 [Codex 验证问题指南](/zh/posts/codex-phone-verification)。这些问题可能紧接在重新登录后出现，但不能继续用“刷新令牌失败”解释。

## 仍然失败时，提交最小而安全的证据

如果你已经在正确主机完成一次全新的官方登录，仍然得到相同报错，可以准备这些材料：

- 脱敏后的报错原文、时间与时区；
- App、CLI 或 IDE 入口及版本；
- 操作系统，以及本地、WSL、SSH、容器或虚拟机环境；
- 当前认证方式，但不提供 token 或完整账号；
- logout 是否成功、新的浏览器或 device flow 是否完成；
- 一个小型验证任务的结果；
- 只有新登录本身失败时，才附上脱敏后的 `codex-login.log` 片段。

不要提交 `auth.json`、任何 token、API Key、验证码、Cookie、完整 HAR 或未打码截图。真正的完成标准不是“重新看到了登录页”，而是正确执行主机上的新凭据已经绑定到预期账号和认证方式，并能完成一个边界清楚的 Codex 任务。
