Repository navigation
[BUG] Codex requests continuously return 502 Bad Gateway after ocx service install in Windows 10 + WSL #2107
Description
Client or integration
Codex CLI
Area
CLI
Summary
After running ocx service install in a Windows 10 + WSL environment, Codex requests continuously return 502 Bad Gateway and the Codex client repeatedly reconnects.
Environment
This issue occurs on Windows 10 when OpenCodex and Codex run inside WSL.
- Host operating system: Windows 10
- Runtime environment: Linux inside WSL
- Repository: https://github.com/lidge-jun/opencodex
- OpenCodex version:
2.26.0 - Service manager: systemd user service inside WSL
- Local proxy endpoint:
http://<LOOPBACK_HOST>:<OPENCODEX_PORT>/v1
- Provider: OpenAI / ChatGPT Codex backend
WSL Proxy Configuration
The Windows host runs a local proxy on <PROXY_PORT>. The proxy environment variables are configured inside WSL using the Windows host address obtained from the WSL default route.
The following configuration is used in WSL:
WIN_HOST=$(ip route | awk '/default/ {print $3; exit}')
PROXY_PORT="<PROXY_PORT>"
LOOPBACK_V4="<LOOPBACK_IP_V4>"
LOOPBACK_V6="<LOOPBACK_IP_V6>"
WILDCARD_IP="<WILDCARD_IP>"
export HTTP_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export HTTPS_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export ALL_PROXY="socks5h://${WIN_HOST}:${PROXY_PORT}"
export NO_PROXY="localhost,${LOOPBACK_V4},${LOOPBACK_V6},${WILDCARD_IP},${WIN_HOST}"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$NO_PROXY"The configuration is persisted in the WSL shell startup file:
# ~/.bashrc
WIN_HOST=$(ip route | awk '/default/ {print $3; exit}')
PROXY_PORT="<PROXY_PORT>"
LOOPBACK_V4="<LOOPBACK_IP_V4>"
LOOPBACK_V6="<LOOPBACK_IP_V6>"
WILDCARD_IP="<WILDCARD_IP>"
export HTTP_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export HTTPS_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export ALL_PROXY="socks5h://${WIN_HOST}:${PROXY_PORT}"
export NO_PROXY="localhost,${LOOPBACK_V4},${LOOPBACK_V6},${WILDCARD_IP},${WIN_HOST}"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$NO_PROXY"Reproduction Steps
- Start Windows 10 and open the WSL distribution.
- Configure the proxy environment variables inside WSL.
- Install and configure OpenCodex inside WSL.
- Run:
ocx service install- Start a conversation with GPT through Codex.
Actual Result
The Codex interface continuously displays:
Reconnecting... 2/5 (19s • esc to interrupt)
The request then fails with:
Unexpected status 502 Bad Gateway:
Provider unreachable:
The socket connection was closed unexpectedly.
For more information, pass `verbose: true` in the second argument to fetch(),
url: http://<LOOPBACK_HOST>:<OPENCODEX_PORT>/v1/responses
The OpenCodex log contains:
[upstream-retry] connection reset (<UPSTREAM_HOST>) — retrying
The request record contains:
{
"provider": "openai",
"status": 502,
"recoveryKinds": ["connection-reset"]
}Comparison
In the same Windows 10 + WSL environment, run:
ocx service uninstallThen install the Codex shim:
After installing the Codex shim, conversations with GPT through Codex complete successfully. The following errors do not occur:
```text
502 Bad Gateway
connection reset (<UPSTREAM_HOST>)
The socket connection was closed unexpectedly
Expected Result
After running ocx service install in the Windows 10 + WSL environment, conversations with GPT through Codex should complete successfully, with behavior consistent with ocx codex-shim install.
环境
该问题发生在 Windows 10 系统中,OpenCodex 和 Codex 运行在 WSL 环境内。
- 主机操作系统:Windows 10
- 运行环境:WSL 中的 Linux
- Repository: https://github.com/lidge-jun/opencodex
- OpenCodex version:
2.26.0 - 服务管理器:WSL 中的 systemd user service
- 本地代理端点:
http://<LOOPBACK_HOST>:<OPENCODEX_PORT>/v1
- Provider:OpenAI / ChatGPT Codex backend
WSL 中的代理配置
Windows 主机上的本地代理监听 <PROXY_PORT> 端口。WSL 中通过默认路由获取 Windows 主机地址,并设置代理环境变量。
WSL 中使用以下配置:
WIN_HOST=$(ip route | awk '/default/ {print $3; exit}')
PROXY_PORT="<PROXY_PORT>"
LOOPBACK_V4="<LOOPBACK_IP_V4>"
LOOPBACK_V6="<LOOPBACK_IP_V6>"
WILDCARD_IP="<WILDCARD_IP>"
export HTTP_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export HTTPS_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export ALL_PROXY="socks5h://${WIN_HOST}:${PROXY_PORT}"
export NO_PROXY="localhost,${LOOPBACK_V4},${LOOPBACK_V6},${WILDCARD_IP},${WIN_HOST}"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$NO_PROXY"配置持久化在 WSL 的 shell 启动文件中:
# ~/.bashrc
WIN_HOST=$(ip route | awk '/default/ {print $3; exit}')
PROXY_PORT="<PROXY_PORT>"
LOOPBACK_V4="<LOOPBACK_IP_V4>"
LOOPBACK_V6="<LOOPBACK_IP_V6>"
WILDCARD_IP="<WILDCARD_IP>"
export HTTP_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export HTTPS_PROXY="http://${WIN_HOST}:${PROXY_PORT}"
export ALL_PROXY="socks5h://${WIN_HOST}:${PROXY_PORT}"
export NO_PROXY="localhost,${LOOPBACK_V4},${LOOPBACK_V6},${WILDCARD_IP},${WIN_HOST}"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$NO_PROXY"复现步骤
- 启动 Windows 10,并进入 WSL。
- 在 WSL 中配置代理环境变量。
- 在 WSL 中安装并配置 OpenCodex。
- 执行:
ocx service install- 通过 Codex 与 GPT 开始对话。
实际结果
Codex 界面持续显示:
Reconnecting... 2/5 (19s • esc to interrupt)
随后请求失败,并显示:
Unexpected status 502 Bad Gateway:
Provider unreachable:
The socket connection was closed unexpectedly.
For more information, pass `verbose: true` in the second argument to fetch(),
url: http://<LOOPBACK_HOST>:<OPENCODEX_PORT>/v1/responses
OpenCodex 日志中出现:
[upstream-retry] connection reset (<UPSTREAM_HOST>) — retrying
请求记录中出现:
{
"provider": "openai",
"status": 502,
"recoveryKinds": ["connection-reset"]
}对比结果
在相同的 Windows 10 + WSL 环境中执行:
ocx service uninstall随后安装 Codex shim:
ocx codex-shim install安装 Codex shim 后,通过 Codex 与 GPT 对话可以正常完成。以下错误不再出现:
502 Bad Gateway
connection reset (<UPSTREAM_HOST>)
The socket connection was closed unexpectedly
预期结果
在 Windows 10 + WSL 环境执行 ocx service install 后,通过 Codex 与 GPT 对话应当能够正常完成,行为应当与执行 ocx codex-shim install 时一致。
Reproduction
- Start Windows 10 and open the WSL distribution.
- Configure the proxy environment variables inside WSL.
- Install and configure OpenCodex inside WSL.
- Run:
ocx service install- Start a conversation with GPT through Codex.
Version
2.26.0
Operating system
Windows 10 22H2, WSL2 2.7.12.0
Provider and model
openai/gpt-5.6-luna
Logs or error output
Screenshots and supporting files
No response
Redacted configuration
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
github-actions commentedon Aug 19, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
coderabbitai commentedon Aug 19, 2026
🔗 Related PRs
#463 - fix(proxy): stop empty 503 bodies becoming Codex Unknown error (
#452) [merged]#581 - Add Traditional Chinese (zh-TW) localization for GUI, README, and docs [open]
#984 - [WRONG BRANCH] 修复 routed 模型路径 429 限流重试缺失 [open]
#1289 - fix(codex): warn when codex-shim install cannot prove routing (
#1169) [merged]#1440 - Add Traditional Chinese (zh-TW) localization for GUI, README, and docs (resync) [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 70 / 80
Windows 10 + WSL2에서
ocx service install뒤에 Codex가/v1/responses로 붙으면 계속 502다. 로그는[upstream-retry] connection reset이고 요청 기록은recoveryKinds: ["connection-reset"]이다. 같은 머신에서 서비스를 지우고ocx codex-shim install하면 살아난다. 리포터는 WSL.bashrc에 Windows 호스트 프록시(HTTP_PROXY/HTTPS_PROXY/ALL_PROXY=socks5h://…)를 넣어 두었다. 기본 native 경로가 서비스 설치 직후 막히지만, 환경은 WSL+외부 프록시 조합이고 shim 우회가 있어서 70이다. 데스크톱 재부팅 기본 사고는 아니라 80은 아니다.502는 프록시 프로세스가 죽은 게 아니다.
src/lib/upstream-retry.ts의fetchWithResetRetry()가 업스트림 소켓 리셋을 재시도하다 포기한 뒤, Responses가Provider unreachable502로 바꾼 것이다. 로컬 OpenCodex는 받아 주고, ChatGPT Codex 백엔드로 나가는 연결이 끊긴다. 서비스일 때만 나고 포그라운드/shim에서는 안 나니, 유닛이 물려받는 아웃바운드 환경이 후보다.src/service.ts의buildUnit()이 유닛에 굽는 값은OCX_SERVICE, Bun 런타임,PATH,CODEX_HOME,CODEX_SQLITE_HOME,OPENCODEX_HOME뿐이다.HTTP_PROXY/HTTPS_PROXY/ALL_PROXY/NO_PROXY는 없다.installSystemd()는 이 유닛을 쓰고systemctl --user enable+restart한다. systemd user 서비스는.bashrc를 안 읽는다.ExecStart는/bin/sh -lc로buildServiceShellCommand()를 돌리는데, 그 스크립트는 API 토큰 파일만 export하고ocx start --port를 exec한다. Ubuntu WSL의/bin/sh는 보통 dash라 로그인 셸이어도.bashrc가 아니라.profile만 본다. 리포터가 프록시를.bashrc에만 넣었다면 서비스 프로세스에는 프록시가 없다.src/config.ts의applyProxyEnv()는config.proxy를 프로세스 env로 미러링한다. 사용자 설정 env가 있으면 그걸 이기고, 없으면 config 값만 넣는다. 이 재현은 config가 아니라 셸 env다. 서비스 유닛이 그 env를 안 구우면applyProxyEnv()도 채워 줄 값이 없다. shim은 대화형 셸에서 Codex를 띄우므로.bashrc프록시를 그대로 inherited한다. 그래서 uninstall + shim이 되는 것이다. WSL 자체는src/codex/home.ts의isWslRuntime()과src/service.ts의 systemd 안내(wsl.conf[boot] systemd=true)로 이미 다루고 있다. 빠진 건 아웃바운드 프록시 전달이다.네이티브 게이트(#2108의 503)와는 증상이 다르다. 여기는 업스트림 전송 실패고, 로컬 admission 펜스가 아니다. 다만 같은 Windows/WSL 서비스 수명 축이다. 유닛에 프록시를 구울 때는
NO_PROXY에 loopback과 WSLWIN_HOST를 빼먹지 말아야 한다. 빠지면 OpenCodex 자신의 loopback이 다시 ent 프록시로 들어가 또 리셋이 난다.해결방안
buildUnit()의envLines에 설치 셸의HTTP_PROXY/HTTPS_PROXY/ALL_PROXY/NO_PROXY(소문자 키 포함)를systemdEnvironmentAssignment()로 굽는다.src/lib/proxy-env.ts의PROXY_ENV_KEYS를 그대로 쓰면 키가 invent되지 않는다.NO_PROXY에는applyProxyEnv()와 같이localhost/127.0.0.1/::1을 넣고, WSL이면 기본 라우트의 Windows 호스트도 넣는다. 유닛만 고치고config.proxy가 비어 있으면 서비스 재시작 후에도 같은 구멍이 남으니,installSystemd()시점에 현재 env를 유닛과 서비스 환경 파일 양쪽에 남기는 편이 안전하다. dash-lc가.bashrc를 안 읽는 전제 때문에 “로그인 셸이니 env는 따라온다”로 넘기면 안 된다. 회귀는 두 갈래다. WSL +.bashrc전용 HTTP_PROXY +ocx service install→ 네이티브 Responses가 502 없이 통과. 프록시 없는 호스트의 유닛에는 빈 Environment 줄을 만들지 않는다.이 댓글은 grok-bot이 작성했습니다
fix(service): bake outbound proxy env into installed service definitions
fix(service): build service definitions from an injected proxy env, n…
lidge-jun commentedon Aug 19, 2026
Fixed on
devas of #2116 (bdaf4463a).buildUnit,buildPlist, andbuildWindowsServiceScriptnow bake the outbound proxy variables into the installed service definition, so a service started by systemd/launchd/Task Scheduler reaches upstream through the same proxy your shell uses. Lower-casehttp_proxyis honored and baked under the canonical upper-case name, so a definition never carries two spellings of one setting. An unset key emits nothing rather than an empty assignment.Closing manually — PRs here target
dev, so GitHub's auto-close does not fire.One thing worth flagging from the follow-up, since it changed the shipped diff. The original tests set the proxy variables on the real
process.envand restored them in afinally. That leaked:bun test a bruns every file in one process, and the Lab sandbox rejects any proxy variable on the live environment as aharness_failure, so 73 unrelated Lab tests failed on macOS CI while passing in isolation. The builders now take the resolved proxy entries as a parameter and the tests hand in a literal environment. Production behavior is unchanged; the default argument is the original call.fix(service): write service definitions owner-only, they can carry a …
fix(service): fail closed on the Windows ACL when a definition holds …
test(service): pin the file mode on POSIX only, not on Windows
fix(service): bake outbound proxy env into installed service definitions
fix(service): build service definitions from an injected proxy env, n…
fix(service): write service definitions owner-only, they can carry a …
fix(service): fail closed on the Windows ACL when a definition holds …
test(service): pin the file mode on POSIX only, not on Windows