Codex 登录端口冲突问题复盘
日期:2026-06-07 问题:Codex 登录时报错
Sign-in failed: failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字的尝试。 (os error 10013)
一、问题现象
在 Windows 终端执行 codex login 时,登录流程失败,终端报错:
Sign-in failed: failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字的尝试。 (os error 10013)二、Codex 登录原理
终端执行 codex login
│
▼
Codex 在本地启动 HTTP 服务器,监听 localhost:3000
│
▼
打开浏览器跳转到 OAuth 登录页面
│
▼
用户授权成功,浏览器回调 http://localhost:3000/callback?token=xxx
│
▼
本地服务器接收 token,完成登录关键依赖:Codex 必须能在 localhost:3000 上成功绑定并监听。
三、根因分析
3.1 Windows 动态端口机制
Windows 在处理外向网络连接时,需要从动态端口池中分配一个临时端口作为本地发送方地址。通过以下命令查看:
netsh int ipv4 show dynamicport tcp该机器的动态端口范围为 1024 ~ 15000。
3.2 冲突原因
| 因素 | 说明 |
|---|---|
| Codex 需要的端口 | 3000(固定) |
| 动态端口范围 | 1024 ~ 15000 |
| 3000 是否在范围内 | 是 |
3000 落在动态端口池内,当系统随机将 3000 分配给某个外向连接作为临时端口后,该端口即被标记为"使用中"。此时 Codex 尝试绑定 3000 进行监听,Windows 返回 WSAEACCES (10013) 错误——不是权限不够,而是端口已被占用。
3.3 为什么 macOS/Linux 不出这个问题
macOS/Linux 的动态端口范围通常从 32768 或 49152 开始,远高于开发常用的 3000/8000/8080,因此几乎不会冲突。
3.4 影响因素
- 开机时间越长,临时端口消耗越多,冲突概率越高
- Docker Desktop / WSL2 / Hyper-V 的 WinNAT 服务会大量预留端口
- 后台网络活动频繁会加速端口分配
四、排查过程
4.1 检查端口是否被进程占用
netstat -ano | findstr :3000结果:3000 端口没有被任何进程监听(LISTENING),但仍无法绑定。
这说明 3000 不是被某个服务"监听"了,而是被系统作为临时端口"标记"了占用。
4.2 检查 WinNAT 服务
sc query winnatWinNAT 服务正在运行,它会预留大量端口范围。
4.3 查看端口排除范围
netsh int ipv4 show excludedportrange protocol=tcp3000 不在任何排除范围内,属于动态端口池的一部分。
4.4 确认动态端口范围
netsh int ipv4 show dynamicport tcp确认起始端口为 1024,覆盖了 3000。
五、解决方案
5.1 永久排除 3000 端口(推荐)
以管理员身份打开 PowerShell 或 CMD,依次执行:
# PowerShell 用分号分隔
net stop winnat; netsh int ipv4 add excludedportrange protocol=tcp startport=3000 numberofports=1; net start winnat# CMD 用 && 分隔
net stop winnat && netsh int ipv4 add excludedportrange protocol=tcp startport=3000 numberofports=1 && net start winnat验证:
netsh int ipv4 show excludedportrange protocol=tcp列表中出现 3000 即成功。此排除永久生效,重启不丢失。
5.2 临时方案(重启后失效)
仅重启 WinNAT 释放当前被占的临时端口:
net stop winnat
net start winnat见效快但不持久,下次遇到同样的端口冲突仍需重复执行。
5.3 终极方案(慎用)
将动态端口范围起始值移到 15000 以后:
netsh int ipv4 set dynamicport tcp start=15000 num=50535一劳永逸,但会改变系统网络行为,影响面较大,仅在其他方案无效时考虑。
六、预防措施
6.1 开发常用端口排除
如果你在本机做开发,建议一次性排除常用端口,避免同类问题:
net stop winnat
netsh int ipv4 add excludedportrange protocol=tcp startport=3000 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=3001 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=4000 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=5000 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=8000 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=8080 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=8443 numberofports=1
netsh int ipv4 add excludedportrange protocol=tcp startport=9000 numberofports=1
net start winnat6.2 识别问题模式
以后遇到类似的 os error 10013 或 EADDRINUSE 报错时,排查思路:
端口绑定失败
│
├─ 有进程在监听? → netstat -ano | findstr :端口号 → taskkill /PID <pid> /F
│
└─ 无进程监听但仍失败? → 动态端口冲突
│
├─ netsh int ipv4 show excludedportrange protocol=tcp(检查是否已排除)
├─ netsh int ipv4 show dynamicport tcp(检查动态端口范围)
└─ 排除目标端口(5.1 方案)6.3 适用于所有 Windows 开发者
该问题不只影响 Codex,任何需要在 Windows 上本地监听端口的服务(开发服务器、OAuth 回调等)都可能遇到。建议新机器环境初始化时就做好端口排除。
七、参考命令速查
| 场景 | 命令 |
|---|---|
| 查看动态端口范围 | netsh int ipv4 show dynamicport tcp |
| 查看已排除端口 | netsh int ipv4 show excludedportrange protocol=tcp |
| 排除单个端口 | netsh int ipv4 add excludedportrange protocol=tcp startport=端口号 numberofports=1 |
| 删除排除规则 | netsh int ipv4 delete excludedportrange protocol=tcp startport=端口号 numberofports=1 |
| 重启 WinNAT | net stop winnat && net start winnat |
| 查看端口占用 | netstat -ano | findstr :端口号 |
八、总结
| 项目 | 内容 |
|---|---|
| 问题本质 | Windows 动态端口范围过大(1024起),覆盖了开发常用端口 |
| 错误码 | WSAEACCES 10013(端口已被系统临时占用,非权限问题) |
| 最佳修复 | 将常用端口加入 excludedportrange(永久排除) |
| 预防手段 | 新机器初始化时批量排除开发端口 |
| 识别口诀 | 10013 + 无进程监听 = 动态端口冲突 |