Summary
On macOS, Codex behaves differently depending on how proxying is provided:
- Works when
HTTP_PROXY / HTTPS_PROXY / ALL_PROXY are explicitly set in the environment
- Works when the machine is using TUN mode
- Becomes very slow or times out when started by
launchd and relying on macOS system proxy (non-TUN), especially on the websocket endpoint:
wss://chatgpt.com/backend-api/codex/responses
Observed behavior
Logs show websocket issues like:
failed to connect to websocket: IO error: Operation timed out (os error 60),
url: wss://chatgpt.com/backend-api/codex/responses
I also observed turns that do not fail immediately, but take ~13 minutes before the first event arrives.
Repro characteristics
Environment:
- macOS
- Codex launched by
launchd (background service / agent)
- Clash Verge system proxy enabled
- non-TUN mode
Behavior comparison:
- Same machine + same proxy node: works when explicit proxy env vars are set
- Same machine + same proxy node: works in TUN mode
- Same machine + same proxy node: becomes unstable when relying on macOS system proxy in launchd/non-TUN mode
This makes it look less like a bad proxy node, and more like different proxy behavior between transports.
Why I think this is a Codex bug
From the source tree:
- Normal HTTP requests use the shared reqwest client builder in
codex-rs/core/src/default_client.rs
- Responses websocket connections do not appear to reuse that client; they directly call
tokio_tungstenite::connect_async_with_config in codex-rs/codex-api/src/endpoint/responses_websocket.rs
Relevant locations:
codex-rs/core/src/default_client.rs (build_reqwest_client)
codex-rs/core/src/client.rs (connect_websocket wiring)
codex-rs/codex-api/src/endpoint/responses_websocket.rs (connect_websocket implementation)
There are also existing comments in the repo mentioning macOS system-configuration issues and no_proxy() workarounds, which seems related:
codex-rs/tui/src/tooltips.rs
codex-rs/rmcp-client/src/auth_status.rs
So it looks like HTTP and websocket transports may not share the same proxy resolution path on macOS.
Expected behavior
Responses websocket transport should honor proxy configuration as reliably as the normal HTTP transport, including macOS system-proxy scenarios.
Suggestion
Consider centralizing proxy handling so websocket transport and reqwest-based HTTP transport share the same proxy resolution logic, or explicitly documenting that websocket transport currently requires environment proxy variables for reliability on macOS.
Summary
On macOS, Codex behaves differently depending on how proxying is provided:
HTTP_PROXY/HTTPS_PROXY/ALL_PROXYare explicitly set in the environmentlaunchdand relying on macOS system proxy (non-TUN), especially on the websocket endpoint:wss://chatgpt.com/backend-api/codex/responsesObserved behavior
Logs show websocket issues like:
I also observed turns that do not fail immediately, but take ~13 minutes before the first event arrives.
Repro characteristics
Environment:
launchd(background service / agent)Behavior comparison:
This makes it look less like a bad proxy node, and more like different proxy behavior between transports.
Why I think this is a Codex bug
From the source tree:
codex-rs/core/src/default_client.rstokio_tungstenite::connect_async_with_configincodex-rs/codex-api/src/endpoint/responses_websocket.rsRelevant locations:
codex-rs/core/src/default_client.rs(build_reqwest_client)codex-rs/core/src/client.rs(connect_websocketwiring)codex-rs/codex-api/src/endpoint/responses_websocket.rs(connect_websocketimplementation)There are also existing comments in the repo mentioning macOS
system-configurationissues andno_proxy()workarounds, which seems related:codex-rs/tui/src/tooltips.rscodex-rs/rmcp-client/src/auth_status.rsSo it looks like HTTP and websocket transports may not share the same proxy resolution path on macOS.
Expected behavior
Responses websocket transport should honor proxy configuration as reliably as the normal HTTP transport, including macOS system-proxy scenarios.
Suggestion
Consider centralizing proxy handling so websocket transport and reqwest-based HTTP transport share the same proxy resolution logic, or explicitly documenting that websocket transport currently requires environment proxy variables for reliability on macOS.