Guides ·
Codex CLI proxy settings: ChatGPT works in the browser, but Codex in the terminal can’t connect or says your region isn’t supported
ChatGPT works fine in the browser, yet Codex in the terminal keeps reconnecting, fails login with “Token exchange failed”, or says your region isn’t supported. The cause is usually simple: Codex is a terminal program that decides whether to use a proxy from environment variables, not from whatever your browser uses. If the terminal has no proxy variables, Codex connects directly from your own network.
OpenAI’s Codex docs don’t cover proxies, and the environment variables page doesn’t list HTTPS_PROXY or its relatives. The rules below come from the source code in the openai/codex repository, checked against release 0.159.2 (2026-09-29). Claims from GitHub issues are marked as user reports.
Which variables Codex reads
- HTTPS_PROXY / https_proxy: the one that matters. Codex talks to OpenAI over HTTPS and WSS, and its ordinary HTTPS requests ignore
http_proxy. - ALL_PROXY / all_proxy: a fallback when HTTPS_PROXY isn’t set. Claude Code, by contrast, ignores ALL_PROXY.
- NO_PROXY / no_proxy: hosts that skip the proxy. Include
localhost,127.0.0.1,::1. - Case: both are read, and when both exist Codex takes the uppercase one. curl does the opposite. If the two hold different values, a curl test and Codex will disagree, so keep one set or make them identical.
- SOCKS: not documented. In the source, Codex’s HTTP client is built without SOCKS support while its WebSocket client accepts
socks5://, so behaviour is inconsistent; users report problems that went away after switching to an HTTP proxy (#20844, #16360). Usehttp://. - System proxy: don’t count on it. The
respect_system_proxyswitch, which makes Codex follow system and PAC settings, is marked under development and off by default. On macOS,codex doctoreven warns “A macOS system proxy is configured but unused”.
Where to set them
macOS / Linux: add these lines to ~/.zshrc or ~/.bashrc, using your proxy app’s HTTP / mixed port, then open a new terminal before starting Codex:
export https_proxy=http://127.0.0.1:7890 export http_proxy=http://127.0.0.1:7890 export no_proxy=localhost,127.0.0.1,::1
Windows PowerShell, current window only, using the $env: syntax from Microsoft’s documentation:
$env:HTTPS_PROXY = "http://127.0.0.1:7890" $env:HTTP_PROXY = "http://127.0.0.1:7890" $env:NO_PROXY = "localhost,127.0.0.1,::1" codex
To keep them, save them at user scope; terminals opened afterwards pick them up:
[Environment]::SetEnvironmentVariable('HTTPS_PROXY', 'http://127.0.0.1:7890', 'User')
[Environment]::SetEnvironmentVariable('HTTP_PROXY', 'http://127.0.0.1:7890', 'User')
[Environment]::SetEnvironmentVariable('NO_PROXY', 'localhost,127.0.0.1,::1', 'User')
- ~/.codex/.env: Codex loads this file at startup and its values override the same variables from your shell (
codex-rs/arg0/src/lib.rs; not in the official docs). If your proxy port changes and this file doesn’t, Codex keeps dialling a dead port and reports “Connection refused” (os error 61 on macOS, 10061 on Windows), as several GitHub reports show (#38885, #44517). - No proxy key in config.toml: a setting for Codex’s own proxy is still an open feature request (#6060).
shell_environment_policy.setonly affects commands Codex runs, not Codex’s own connections.
Alternatively, switch your proxy app to TUN / enhanced mode so it captures all traffic and the terminal needs no settings.
Login: the browser part isn’t the whole story
Per the authentication docs, codex login opens a browser, and after you sign in the browser hands the credentials back through a local callback (localhost:1455 by default). In the source, Codex then exchanges them for tokens at auth.openai.com itself, over the terminal’s network settings. That is how the browser can succeed while the terminal reports Token exchange failed; several users under #10466 traced it to a terminal that wasn’t using the proxy (user reports, not an official diagnosis).
- On remote or headless machines, or when your network blocks the localhost callback, the docs recommend device code login:
codex login --device-auth(beta; enable it in your ChatGPT security settings first). codex login statusshows the active method, andcodex-login.login your log directory records failed attempts.
Sandboxed commands are a separate path
Codex’s own traffic to OpenAI is separate from the commands it runs for you (npm install, git, curl). The security docs say the default workspace-write sandbox in the CLI and IDE extension gives commands no network access unless you enable it:
[sandbox_workspace_write] network_access = true
- Commands inherit Codex’s full environment by default (
shell_environment_policy.inheritdefaults to all), proxy variables included. Withcoreornonethey’re dropped; add them back withshell_environment_policy.set. - The experimental
features.network_proxyroutes commands through Codex’s own domain-filtering proxy, which by default (allow_upstream_proxy) chains to an upstream proxy from the environment. The docs note it doesn’t cover the client’s own model and authentication requests. - In the source, the Windows sandbox fills in proxy variables pointing to
http://127.0.0.1:9when network access is off. Seeing that address in command output means the sandbox has no network, not that your proxy is wrong.
IDE extension and desktop app
The docs say the CLI and IDE extension share configuration and cached login. Apps launched from the Dock or Start menu, though, may not see variables set in ~/.zshrc, and GitHub has several reports of this (#30695, #34955). TUN mode is the simplest fix; if you use ~/.codex/.env, keep it in step with your proxy port.
Checking the exit
First, know which host matters. In the source, ChatGPT sign-in sends model requests to chatgpt.com/backend-api/codex, an API key sends them to api.openai.com/v1, and login uses auth.openai.com.
On macOS / Linux, in the same terminal you run Codex from:
curl -sL ipjudge.org/en/cc | bash
The script lists the terminal’s proxy variables, uses curl with those variables to read the IP and country that api.openai.com and chatgpt.com see, and flags mainland China, Hong Kong or Macau. It also warns when these exits differ from the Anthropic ones or when the macOS system proxy is on but unused by the terminal, and shows the direct exit for comparison. Read-only. It tests curl, not Codex: it ignores ~/.codex/.env and uses the opposite case order, so check those two yourself.
In Windows PowerShell, call curl.exe (in Windows PowerShell 5.1, curl is an alias for Invoke-WebRequest) and read the ip= and loc= lines:
curl.exe -s https://chatgpt.com/cdn-cgi/trace curl.exe -s https://api.openai.com/cdn-cgi/trace
To see which variables the Codex process itself picked up, including any from ~/.codex/.env, run codex doctor and look at its network check.
Once the exit is right, its country must be on OpenAI’s supported list. Mainland China, Hong Kong and Macau aren’t, and the page warns that access from elsewhere may get an account blocked or suspended. For the error itself, see what unsupported_country_region_territory means.
FAQ
ALL_PROXY=socks5://… works for curl, so why is Codex flaky?
Codex reads ALL_PROXY, but its HTTP client has no SOCKS support, so some connections fail. Point it at your proxy app’s HTTP / mixed port as http://127.0.0.1:PORT.
The browser login worked but the terminal says Token exchange failed. What now?
The token exchange runs inside Codex, in the terminal. Set HTTPS_PROXY there and run codex login again; if the callback itself can’t get through, use codex login --device-auth.
Nothing is set in my terminal, so why is Codex using a proxy?
Look in ~/.codex/.env. Codex loads it at startup and it overrides your shell.
Can Codex just use the macOS or Windows system proxy?
Don’t rely on it. respect_system_proxy is still under development and off by default, and users report that even with it on, not every connection follows the system proxy (#39237). Environment variables or TUN mode are more dependable.
Related: Claude Code / Codex exit check · Claude Code proxy settings · Which IP do ChatGPT and Claude see? · ChatGPT check · Method
Which kind of IP do you have?
Check my IP for free