故障处理

终端能联网,Codex 任务却连不上?DNS、代理与网络权限排查

终端访问正常,Codex 任务却报 EAI_AGAIN、连接超时或 network access denied?先对照执行环境与同一目标,再排查 DNS、代理、证书和网络权限,最后用原项目命令验证。

你在终端能下载依赖、访问 API,Codex 执行项目任务时却连不上网。先保留原命令、第一条错误和实际访问的目标,再比较两次执行的环境。终端成功是有用的对照,但还不能证明任务失败一定由沙箱造成。

本文处理的是 Codex 任务命令及其子进程的联网问题,例如包管理器下载、测试访问服务或脚本请求接口。Codex 能正常回复、搜索网页,甚至浏览器能打开同一个网站,都不能替代这条命令的联网验证。若错误是找不到 npm、node 或 python,先看 任务运行时与 PATH 排查;命令尚未启动时,还没有到网络排查阶段。

先看错误发生在哪一层

现象或错误 目前能判断什么 下一步
EAI_AGAIN、ENOTFOUND 解析阶段失败;尚未确定原因 对照环境、DNS / 代理
ECONNREFUSED、连接超时 连接未建立,或等待超时 查目标端口、服务、代理与策略证据
证书校验或 TLS 握手失败 已进入 TLS 相关阶段 核对任务运行时的证书信任与代理
明确提示网络被禁用、目标被策略拒绝 有网络权限或域名规则线索 查实际生效配置与拒绝目标
HTTP 401、403、407、429 已收到某个 HTTP 服务或代理的响应 识别响应来源,再查认证、策略或限流

完整日志中的 getaddrinfo EAI_AGAIN 或 curl 的 Could not resolve host,都应从解析阶段查起。搜索 codex dns error 或 codex network access denied 时,先用这张表定位。单独一个 EAI_AGAIN 不能证明 Codex 禁用了网络;HTTP 403 也可能来自目标服务、企业网关或代理,不能直接当作本地权限拒绝。超时同样不足以单独确定是 DNS、代理还是服务端故障。

1. 在真正失败的位置,建立同一目标的对照

适用情况: 终端正常、任务失败,但执行位置和连接差异还不清楚。

先记录客户端及其版本:桌面应用、CLI 或 IDE 扩展。再确认失败命令实际运行在本机、WSL、SSH、容器还是云端,以及所在项目目录。Windows 终端成功而任务在 WSL 中失败,是两个环境的对照;本机代理的回环地址也不能直接当成另一台机器的代理地址。

可以让 Codex 先做下面这次诊断:

先保留刚才失败的原命令和第一条错误,不修改配置或权限。
在同一个执行主机、项目目录和命令工具里,确认实际运行环境,
记录目标主机、协议、端口,以及是否经过代理。
只检查相关代理、证书变量是否存在,不输出凭据或完整环境。
用已获准的无副作用地址做一次请求,报告退出状态和 HTTP 状态。
如果需要换主机、工具、权限或目标,请先说明这会改变对照条件。

选择原目标上允许访问、无副作用且不含凭据的健康检查或公开资源。在能成功的终端和失败任务的同一个命令工具中分别请求它。下面的 example.com 只演示语法;实际比较前,换成已确认的目标,不为测试任意网站扩大许可。

macOS / Linux,Bash 或 zsh:

network_rc=0
curl --silent --show-error \
  --connect-timeout 10 --max-time 20 \
  --output /dev/null --write-out 'http=%{http_code}\n' \
  'https://example.com/' || network_rc=$?
printf 'curl_exit=%s\n' "$network_rc"

Windows PowerShell,使用真正的 curl.exe:

curl.exe --silent --show-error `
  --connect-timeout 10 --max-time 20 `
  --output NUL --write-out 'http=%{http_code}\n' `
  'https://example.com/'
$networkCurlExit = $LASTEXITCODE
Write-Output "curl_exit=$networkCurlExit"

怎样读结果: 这组命令使用 GET,限制等待时间,丢弃响应正文,没有添加认证信息。按 curl 官方说明,退出码 5 / 6 分别是代理 / 目标解析失败,7 是连接失败,28 是超时,35 / 60 指向 TLS 握手 / 证书校验。http=000 表示没有取得 HTTP 状态,不是一种服务器状态码。这里没有使用 --fail,所以 HTTP 4xx 时 curl 仍可能退出 0,必须同时看两项。

预期结果与下一步: 两边都失败,先查共有的目标或网络问题;只有任务失败,再沿第 2、3 步查差异。两边 curl 都有响应而原脚本失败,直接比较第 4 步的运行时、真实请求和证书,不继续盲目改网络开关。curl 与 Node、Python、包管理器不是同一套网络实现,这次请求只用于缩小范围。

若目标返回重定向,先核对响应中的目标地址,再检查原程序实际跟随到的主机。不要把测试换成别的网站,或只允许入口域名后就认定下载链路完整可用。

2. DNS、代理与证书:先查任务拿到了什么

适用情况: 两边主机或进程环境不同,出现解析错误、代理连接失败或 TLS 错误,尚无明确策略拒绝证据。

先比较代理变量是否存在,以及任务是否通过 Codex 管理的代理执行。在 Bash / zsh 中可以只列出状态,不打印值:

for network_var in http_proxy https_proxy HTTP_PROXY HTTPS_PROXY \
  all_proxy ALL_PROXY no_proxy NO_PROXY \
  SSL_CERT_FILE SSL_CERT_DIR CURL_CA_BUNDLE NODE_EXTRA_CA_CERTS; do
  if printenv "$network_var" >/dev/null; then
    printf '%s=set\n' "$network_var"
  else
    printf '%s=unset\n' "$network_var"
  fi
done

PowerShell 可通过 Get-ChildItem只列出这些变量的名称:

Get-ChildItem Env: |
  Where-Object Name -Match '^(https?_proxy|all_proxy|no_proxy|SSL_CERT_FILE|SSL_CERT_DIR|CURL_CA_BUNDLE|NODE_EXTRA_CA_CERTS)$' |
  Select-Object -ExpandProperty Name

有变量不代表值正确,也不代表原程序支持它。只在本地核对必要的协议、主机、端口、绕过规则和证书文件路径;公开日志不要带代理用户名、密码、Token 或完整环境。

然后按已观察到的差异处理:

  1. 代理只存在于成功终端。 查桌面或 IDE 的实际启动环境、shell 初始化,以及适用执行端的环境过滤。官方的 shell environment policy会影响传给子命令的变量;同时核对原程序自己的代理配置。只补项目需要的项,保存工作并重新加载对应客户端,再回同一目标复验,不用继承全部环境来试运气。
  2. 任务里出现了不同代理。 先识别它是不是当前生效的 Codex 网络代理。不要用终端的整套代理变量覆盖它;如有企业上游代理,按当前执行端与组织支持的链路配置,由实际连接错误确认代理是否可达。任务在远程环境时,应从那个环境验证代理,而不是只在宿主机验证。
  3. 目标域名解析失败。 查拼写、实际解析的主机,以及该环境需要的 VPN / 内网解析是否可用。代理主机解析失败与业务域名解析失败要分开记录。确认同一主机上普通终端也失败时,按组织网络流程处理;不把改公共 DNS 或固定写 IP 当成默认修复。
  4. TLS / 证书失败。 核对系统时间、目标主机名,以及原运行时实际使用的信任库。若组织代理使用自己的 CA,通过组织认可的方式提供证书,并确认任务能读取相应文件;curl 成功不能证明 Node 或 Python 已信任同一证书。不用关闭证书校验来作为修复验收。

验证: 调整哪一项,就先验证那一项:代理从任务环境可达、原程序读到需要的配置、证书校验正常,再重跑原请求。DNS 探测和代理转发的解析路径可能不同,单独一次域名解析成功也不能证明 HTTPS 全链路可用。若仍有明确策略拒绝,进入下一步;若已变成 HTTP 状态错误,进入第 4 步。

3. 有网络权限线索:确认当前到底使用哪套配置

适用情况: 任务报告网络禁用或目标被拒绝,或者环境对照后需要核实 Codex 的命令网络策略。

官方权限文档把本地命令权限与其他联网能力分开。先确认出错的是本地沙箱命令;MCP 连接、浏览器、搜索、模型及认证请求有各自的连接和控制。云端任务要查实际云端环境的网络设置,本机 config.toml 的这段配置不能直接当作云端修复方法。

在支持的本地 CLI 中,使用 /status 查看会话状态,使用 /debug-config核对配置层、启停状态与管理策略来源。其他客户端按其可用诊断入口检查。若当前版本没有该命令,保留版本和启动参数,按 配置加载排查确定路径、profile 与覆盖来源;不要仅凭文件中写了 true 判断已生效。

使用新版权限 profile 的本地环境

权限 profile 当前属于 Beta。已经使用这套机制,且组织允许调整时,在实际生效的 profile 中检查网络开启、代理开启和目标规则三个条件。下面假设现有 profile 就叫 project-edit,仅演示要合并的网络部分,不是一份完整配置;名称不同时换成当前名称,已有同名表时合并内容:

[features]
network_proxy = true

[permissions.project-edit.network]
enabled = true

[permissions.project-edit.network.domains]
"example.com" = "allow"

把示例域名替换成错误日志确认需要且已获准的精确目标,保留 profile 原有文件权限与其他配置。还要确认顶层 default_permissions 实际选中了该 profile;仅定义一个未选中的表不会让当前任务使用它。

生效组合 命令网络行为 排查重点
网络关闭 命令不能联网 核对当前网络许可
网络开启,代理未启用 可直接联网,profile 域名规则不执行 域名表不等于过滤已生效
网络开启,代理启用 代理执行域名规则 核对允许项、拒绝项与真实目标

管理员也可能通过受管理的网络要求启用代理。不要为“让表生效”关闭它。代理生效时,没有允许域名会拦截外部目标,deny 优先于 allow;*.example.com 不包括根域名,**.example.com 才包括根域与子域。优先添加确认需要的精确主机,别用全局通配符掩盖遗漏的重定向或下载主机。

仍使用旧版 sandbox 设置的本地环境

如果当前有效设置是 workspace-write,官方旧机制使用下面的网络开关:

[sandbox_workspace_write]
network_access = true

这会允许命令联网,本身不提供精确域名过滤。需要过滤时,还须按 官方网络代理说明配置并验证对应策略,不把新版 profile 的域名表直接拼进来。只有明确需要联网且允许该范围时才修改,不能把这段当成所有模式的通用开关。

两套机制不能混用:按当前官方规则,加载的配置中出现旧 sandbox_mode、启动时传了 --sandbox,或所选配置 profile 设置了旧模式时,会使用旧机制;受管理的权限 profile 允许列表另有优先约束。若选择新版机制,应按官方迁移说明清理旧设置并验证;不必为了这次排障强行迁移整套配置。

验证: 保存工作,按客户端流程重新加载或启动新会话,保持同一项目与目标;先核对配置诊断,再用正常任务工具重试获准请求。批准一次沙箱外运行成功,只能说明那次执行成功,不能证明普通任务已经修好。approval_policy = "never" 只是审批行为设置,不会自动授予联网权限;受管理策略拒绝时,应把证据交给管理员处理。

如果只有本地开发服务或内网地址失败,核对服务实际监听的主机、端口,以及任务中的 localhost 指向哪里。启用代理时还有默认的本地 / 私网防护;官方支持精确本地目标规则,并对解析到私网的主机另设约束。仅在确实需要、允许访问且确认边界后按 本地网络说明处理,不默认放开整个私网或修改代理监听地址。

4. curl 有响应,原项目请求仍失败

适用情况: 同一任务工具的探测已取得响应,但安装依赖、测试或 API 脚本仍报错。

回到原程序的第一条错误,核对它实际请求的主机、端口、协议和运行时。包管理器可能先访问 registry,再下载另一个主机上的归档;API 可能需要独立认证。只测试首页、缓存命中或换一个镜像成功,都不能证明原请求恢复。

  • HTTP 401 / 403: 先识别是业务服务、代理还是策略生成的响应,再核对请求身份和允许范围。不要通过输出认证头证明凭据存在。若是 Codex 自身登录失败,转到 登录与 401 排查。
  • HTTP 407: 检查实际代理的认证要求与原程序支持的配置方式,不把业务 API Key 填到代理认证里。
  • HTTP 429: 按响应来源处理限流与重试,不继续扩大网络权限。
  • 只有原运行时失败: 比较它自己的代理支持、证书信任、项目配置及子进程环境;只修已证实的差异。MCP 的握手、认证或工具调用超时,另见 MCP 连接排查。

验证: 原程序访问到了原目标,得到预期业务响应。若只是错误从 DNS 变成了 401,说明链路推进了,但业务任务仍未完成;继续处理新阶段,不把它报告成全部修复。

5. 回到原任务,确认修复能持续生效

适用情况: 已找到一项具体原因并完成调整。

从原客户端的正常任务入口,在原执行环境和项目目录中重新运行原命令与原参数,检查退出状态、实际检查范围和产物。例如下载任务要真的取得需要的依赖,接口测试要取得预期状态与数据;只出现“命令执行过”或 curl 退出 0 不够。

再发起一次新的正常任务调用复验,确认修复没有只停留在临时 shell、一次审批或缓存中。保留项目原有验收标准;如果发现新问题,记录当前第一条错误。对有写入、计费或其他副作用的任务,仍按原项目约束执行,不为了验证重复提交业务操作。输出和退出状态难以判断时,可参考 codex exec 验收方法。

仍失败时,整理:客户端版本、实际执行环境、工作目录、脱敏后的原命令、目标主机与端口、第一条错误、终端 / 任务对照、HTTP 与退出状态、有效权限机制,以及每次单项修改后的结果。只提供相关配置片段,去除凭据、Cookie、私有路径和代理认证信息。这份记录比“终端可以,Codex 不行”更容易让维护者继续定位。

本文于 2026-10-17 核对官方资料。文中的 curl 结果判读与环境变量检查在 macOS 隔离测试中验证;没有更改真实 Codex 网络配置,没有调用模型,也没有复现所有客户端、企业代理或 Windows 环境的故障。产品权限行为以所链接的官方文档及当前执行端实际诊断为准。

社区讨论

补充你的经验或问题

评论由 GitHub Discussions 承载;参与讨论需要登录 GitHub。