2151 words
11 minutes
Codex 登录失败排查:Windows 保留端口与 os error 10013

在 Windows 上登录 Codex 客户端时,我遇到了一个看起来像账号问题、实际卡在本地端口上的故障:点击“继续登录”,客户端提示无法启动登录服务器,错误码是 os error 10013

排查发现,登录需要的 1455 端口落在 Windows 的排除端口范围 1359–1458 内。临时停止 WinNAT 后,登录成功;随后重新启动 WinNAT,客户端仍能正常使用。

这次排障最值得记住的是:没有进程监听某个端口,并不意味着应用就能绑定它。

问题现象:登录服务器还没启动就失败了#

当时的完整报错是:

登录失败:failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字的尝试。 (os error 10013)

报错中有两条线索:failed to start login server 指向本地登录服务启动失败,10013 则是 Windows Winsock 的 WSAEACCES,表示套接字访问被拒绝。

排查重点因此落在本地网络绑定环节。仅凭这条报错,还不能判断账号或远端服务是否存在其他问题。

本次涉及的本地地址是:

127.0.0.1:1455

浏览器登录需要把认证结果交回本地客户端,因此客户端会先启动一个回调服务。OpenAI 的认证文档也说明,Codex CLI 的浏览器登录使用本地回调,默认地址为 localhost:1455。这能解释此类流程对本地端口的依赖;其他客户端或版本应以实际日志为准。OpenAI 认证文档

本文记录的是这次 Codex Windows 客户端的故障,不把它泛化为所有 ChatGPT 客户端的登录机制。

排查过程:从监听进程查到系统排除范围#

先检查端口是否被占用#

最直接的检查方式是:

Terminal window
netstat -ano | findstr :1455

需要留意输出中的本地地址、状态和 PID:文本匹配到 1455,不一定代表本地 1455 正在监听。PowerShell 也可以直接筛选监听状态:

Terminal window
Get-NetTCPConnection -LocalPort 1455 -State Listen -ErrorAction SilentlyContinue

如果查到监听进程,可以通过实际 PID 确认程序身份,再决定如何处理:

Terminal window
# 将 12345 替换为查询到的实际 PID
Get-Process -Id 12345

本次没有查到监听 1455 的进程,但客户端依然无法启动登录服务。这说明,检查不能停在“哪个程序占用了端口”这一层。

再检查 Windows 排除端口范围#

在管理员 PowerShell 中查看 IPv4 TCP 排除范围:

Terminal window
netsh interface ipv4 show excludedportrange protocol=tcp

本次输出中包含:

开始端口 结束端口
---------- ----------
1359 1458

1455 位于这个区间内。这是比“机器上装过虚拟化软件”更直接的线索:目标端口确实处于系统排除范围。

如果应用监听 IPv6 地址,还需要检查对应范围;IPv4 和 IPv6 的结果不能相互替代:

Terminal window
netsh interface ipv6 show excludedportrange protocol=tcp

netstat 展示连接和监听状态,而排除范围属于另一类系统网络状态。因此,“没有监听进程”和“端口受系统限制”可以同时成立。

错误码是线索,不能单独定因#

这两个错误码需要区分:

错误码名称排查含义
10048WSAEADDRINUSE地址已在使用,优先检查绑定冲突
10013WSAEACCES访问被拒绝,需要结合权限、绑定方式和系统端口状态判断

不能把它们机械理解成“10048 就是进程占用,10013 就是系统保留”。微软文档指出,其他应用、服务或内核驱动独占绑定同一地址,也可能触发 10013Microsoft Winsock 错误码说明

本次判断依赖的是一组证据:没有发现监听进程、目标端口落入排除范围,以及后续停止 WinNAT 后登录恢复。

本次处理:暂时停止 WinNAT,完成登录后恢复#

WinNAT 与 Windows 的 NAT 网络功能有关。停止它可能影响依赖相关网络的虚拟机、容器或其他任务,因此操作前应先确认这些任务可以暂时中断。

以下步骤在本次排障中有效,不是所有 10013 错误的通用修复方法。

1. 停止 WinNAT#

在管理员 PowerShell 中执行:

Terminal window
net stop winnat

确认服务成功停止后,再尝试登录。如果停止失败,不应假设端口限制已经解除。

2. 重新发起客户端登录#

重新打开客户端的登录流程,点击“继续登录”,随后在浏览器中完成认证。

本次操作后,本地登录服务器成功启动,客户端也成功获得登录状态。

3. 恢复 WinNAT#

登录完成后执行:

Terminal window
net start winnat

如果前面成功停止了服务,即使登录没有成功,也应恢复服务。恢复后可以检查状态,并确认原先使用的虚拟机或容器网络正常:

Terminal window
Get-Service -Name winnat

本次恢复 WinNAT 后,Codex 仍然能够正常使用。

为什么有效,以及这个结论的边界#

本次观察支持的解释是:WinNAT 相关的网络状态影响了目标端口的可绑定性;停止服务后,这个阻碍暂时消失,使本地登录回调服务能够启动。

不过,现有记录没有追踪该排除范围究竟由哪个组件创建,也没有记录停止前后的完整端口范围变化。因此,不宜断言一定是 HNS、WSL2、Docker 或 Podman 中的某一个组件造成了故障。

简化后的登录过程是:

客户端启动本地回调服务
浏览器完成账号认证
认证结果回到本地客户端
客户端保存并使用登录状态

本地回调服务承担登录阶段的工作。OpenAI 文档说明,Codex 会缓存认证信息并在使用期间刷新令牌,这解释了为什么恢复网络服务后,已经建立的登录状态仍可继续使用。OpenAI 登录缓存说明

这次处理只验证了“完成当前登录”的效果。如果以后退出账号、凭据失效或需要重新认证,且端口冲突仍然存在,问题可能再次出现。这是临时绕过,不能据此宣称已经永久修复。

下次遇到类似问题,如何少走弯路#

可以按下面的顺序缩小范围:

  1. 确认失败环节和端口。 从报错或日志中确认是否是本地服务绑定失败,不要预设所有客户端都使用 1455
  2. 检查监听进程。 如果有结果,确认本地地址、状态和进程身份。
  3. 检查对应协议的排除范围。 无监听结果时,也要考虑系统对端口使用的限制。
  4. 根据证据选择验证动作。 只有在相关证据指向 WinNAT、且能接受网络中断时,才考虑本文的临时处理。
  5. 恢复服务并复查。 同时验证客户端登录结果和原有网络任务,保留操作前后的记录。

如果需要继续调查系统端口策略,可以先做只读检查:

Terminal window
netsh int ipv4 show dynamicport tcp

动态端口范围与排除端口范围不是同一个概念,不能看到端口冲突就直接重设动态端口策略。本次没有通过修改全局端口范围解决问题,也没有验证这类修改的长期效果。

另外,如果实际使用的是 Codex CLI,官方文档提供了设备码登录方式,用于本地回调受阻等场景;能否使用取决于账号或工作区设置。这不是本次执行的步骤,也不代表桌面客户端一定提供相同入口。OpenAI 设备码登录说明

留下的经验:把端口可用性拆成两层检查#

这次故障暴露了一个容易忽略的区别:进程有没有使用端口,与系统是否允许应用使用端口,是两个问题。

在带有虚拟网络的 Windows 开发环境中,仅查看监听进程往往不足以解释所有绑定失败。把错误码、监听状态、排除范围和实际操作结果放在一起,才能建立比较可靠的判断。

对这次案例而言,最有复用价值的是在 netstat 没有结果时,知道下一步该检查什么。

Codex 登录失败排查:Windows 保留端口与 os error 10013
https://blog.doracoin.cc/posts/2026/2026-09-11-codex登录失败与windows保留端口/
Author
Doracoin
Published at
2026-09-13
License
CC BY-NC-SA 4.0