openai / openai/codex

Stale proxy in $CODEX_HOME/.env causes misleading macOS `os error 61`; clean home works

Open
#38,885 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug connectivity session
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

Confirmed root cause

This was ultimately caused by a stale proxy configuration in $CODEX_HOME/.env (default: ~/.codex/.env), not by Clash Verge Rev, DNS, TUN/Fake-IP, the proxy node, ChatGPT Plus authentication, database corruption, or a Codex binary regression.

The affected .env was only 135 bytes and defined:

  • HTTP_PROXY
  • HTTPS_PROXY
  • ALL_PROXY
  • NO_PROXY

The first three variables pointed to a loopback proxy on 127.0.0.1:7890. Nothing was listening on that port anymore. Codex therefore attempted to reach OpenAI through a dead local proxy and surfaced only the destination URL:

failed to connect to websocket: IO error: Connection refused (os error 61),
url: wss://chatgpt.com/backend-api/codex/responses

Falling back from WebSockets to HTTPS transport.
stream disconnected before completion: Connection refused (os error 61)

This was misleading because it looked like an OpenAI, WebSocket, VPN, DNS, or routing failure. The actual refused connection was the hidden local proxy hop.

Minimal causal reproduction

All tests used the same Mac, account, authentication, network, proxy node, application bundle, and bundled Codex binary (0.148.0-alpha.9).

  1. Start with a clean recovery CODEX_HOME: the request returns OK.
  2. Copy only the old .env into that working home. Do not copy any chat, database, config, cache, or runtime file.
  3. Run:
CODEX_HOME="/path/to/recovery-home" \
/Applications/ChatGPT.app/Contents/Resources/codex \
exec --skip-git-repo-check "Reply with exactly: OK"
  1. The exact original failure is reproduced: WebSocket Connection refused (os error 61), followed by failed HTTPS fallback.
  2. Move the .env out of the recovery home.
  3. Run the identical command again: it immediately returns OK.

This establishes file-level causality. All discovered SQLite databases also passed integrity_check.

Resolution

Before deleting or replacing the entire Codex state directory:

  1. Fully quit the ChatGPT/Codex desktop app.
  2. Determine the active home:
CODEX_HOME_DIR="${CODEX_HOME:-$HOME/.codex}"
  1. Check whether $CODEX_HOME_DIR/.env exists.
  2. Inspect only the proxy-related keys locally. Do not paste the complete file into an issue or AI chat because proxy URLs can contain credentials.
  3. For every loopback proxy address found, verify that the port is actually listening:
lsof -nP -iTCP:7890 -sTCP:LISTEN
  1. Back up the file, then remove or correct only the stale proxy configuration.
  2. Relaunch Codex and test with the bundled CLI.

In this case, excluding the stale .env restored the current desktop app and bundled CLI without changing Clash, DNS, TUN, the OpenAI account, or the application version.

First checks for AI troubleshooting agents

If a user reports any of the following:

  • error sending request
  • Connection refused (os error 61)
  • repeated Reconnecting... waiting for network
  • WebSocket failure followed by HTTPS fallback failure
  • browser/curl works but Codex does not

Do these checks before recommending reinstalling the app, changing DNS, disabling TUN, switching proxy clients, rotating nodes, logging out, or deleting ~/.codex:

  1. Inspect $CODEX_HOME/.env (default ~/.codex/.env).
  2. Enumerate HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY and lowercase equivalents without exposing credentials.
  3. Check whether every referenced 127.0.0.1/loopback proxy port has a listening process.
  4. Also inspect process/launch environment and macOS system proxy settings, but do not assume they are the only proxy sources.
  5. A/B test the same Codex binary with:
    • the affected CODEX_HOME
    • a clean temporary CODEX_HOME
  6. If the clean home works, compare small environment/config/runtime files before touching session databases.
  7. Never advise deleting ~/.codex without first making a complete backup; it contains local chats, projects, session indexes, and related state.

The highest-value first question is:

Does $CODEX_HOME/.env define a proxy, and is that local proxy port actually listening?

Recovering chats and projects safely

The clean-home test made old chats/projects disappear from the sidebar, but they were not deleted. They remained in the backed-up Codex home.

The durable data was found in:

  • sessions/**/*.jsonl
  • archived_sessions/*.jsonl
  • session_index.jsonl
  • state_5.sqlite
  • thread_history_1.sqlite
  • sqlite/codex-dev.db
  • .codex-global-state.json
  • history.jsonl
  • memories_1.sqlite and memories/

A recovery lab was built from a known-good home, then user-data groups were migrated without the stale .env, old auth/config, locks, sockets, logs, caches, WAL/SHM sidecars, shell snapshots, or process-manager state.

Validated recovery result:

  • 174/174 old session files recovered and parsed
  • 103 active sessions
  • 71 archived sessions
  • 174 old thread records
  • 11 projects
  • 19 thread-to-project associations
  • all active SQLite databases: integrity_check=ok
  • the bundled 0.148.0-alpha.9 still returned OK after every recovery group

For most affected users, simply backing up and removing/correcting the stale .env in the original home should preserve all chats and projects. The selective migration was used here only because a clean home had already been installed during troubleshooting.

Environment

  • ChatGPT/Codex Desktop: 26.810.41047 (build 6570)
  • Bundle ID: com.openai.codex
  • Bundled Codex CLI: 0.148.0-alpha.9
  • Subscription: ChatGPT Plus
  • Platform: macOS, Apple Silicon (arm64)
  • Proxy client: Clash Verge Rev

Why the earlier diagnostics were misleading

The affected network path itself was healthy:

  • Clash Verge Rev TUN + Global mode was working.
  • chatgpt.com resolved into the Fake-IP range and routed through the TUN interface.
  • TLS reached chatgpt.com.
  • GET /backend-api/codex/responses reached OpenAI and returned the expected 405 Method Not Allowed with allow: POST.
  • Stable Codex 0.144.4 worked with a clean home.
  • The bundled 0.148.0-alpha.9 also worked with that same clean home.
  • Removing only config.toml did not help.

Those results correctly pointed to persistent state outside config.toml, but the error message did not reveal the effective proxy source or the refused local proxy address.

Requested product improvements

  1. Include the effective proxy target (with credentials redacted) in transport diagnostics.
  2. Identify the source of the proxy setting, such as process environment vs. $CODEX_HOME/.env.
  3. When a loopback proxy returns ECONNREFUSED, show an actionable message such as:
    Local proxy 127.0.0.1:7890 is not listening; check $CODEX_HOME/.env.
  4. Add a diagnostics command/page that reports effective network configuration safely.
  5. Avoid presenting a failed local proxy hop only as an error for the final chatgpt.com URL.

A 135-byte stale .env caused hours of unnecessary investigation across DNS, TUN, WebSockets, versions, authentication, nodes, and reinstall attempts. Surfacing the effective proxy would make this failure immediately actionable.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure with the bundled CLI and compare the affected CODEX_HOME against a clean temporary home, focusing on .env proxy variables and the loopback port. Done means transport diagnostics safely report the effective proxy target and source, and identify an unlistening local proxy instead of showing only the final chatgpt.com URL.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, networking, observability
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.