When Codex stalls, interrogate the transport before you blame the model
Social feeds still collapse every flaky AI client into “OpenAI is down,” but the Codex CLI reports pain with deliberately vague language. A run can freeze mid‑stream, lose chunks after a long reasoning pass, or fail the moment it tries to refresh a ChatGPT‑linked credential. The superficial resemblance to overloaded API clusters is dangerous because overseas transit issues, middleboxes that reset idle HTTP/2 flows, and domestic DNS that returns addresses your split routing never tags as OpenAI produce the same user-visible timeout string. Start every investigation by classifying failures: if the TLS handshake never completes, you are fighting the wire; if you receive crisp JSON with an HTTP error code and latency headers, you might truly be dealing with rate limits or incidents.
The CLI stack is also a fan‑out graph. One worker might speak HTTPS to api.openai.com for models, another might call chatgpt.com surfaces during auth, onboarding wizards can bounce to platform.openai.com documentation, and language tooling may download runtimes or skill bundles from github.com and npm CDNs before your first prompt ever hits the model. Any of those legs can be direct while the others accidentally traverse a mis‑ordered MATCH rule, which feels like “random” unreliability until you read the connection board. Your operational goal is to make every leg observable, stable, and explicitly routed whenever policy wants offshore exit—not to carpet‑bomb every packet through a single tunnel.
Why ChatGPT in a browser outpaces the terminal agent
Chromium honors the macOS or Windows system proxy table with boring consistency. Many CLI runtimes are chaos by comparison. Go’s net stack respects HTTPS_PROXY only when the environment is clean; Node‑based helpers may spawn child processes that forget inherited variables; tools compiled for HTTP/3 might skip classic CONNECT proxies entirely. A successful curl in one shell and a failing Codex CLI session in another therefore share a laptop yet disagree on which packets leave the country. The sustainable fix is not tattooing six export lines into every profile—it is lifting interception to the kernel dataplane with TUN so policy precedes userland arguments about environment blocks.
Treat TUN as disciplined interception, not a meme setting. Frames that would have marched toward congested default routes instead land inside Clash, where split routing decides whether they should ride a low‑loss offshore node or remain DIRECT for domestic SaaS. The architecture mirrors what we already recommend for Discord voice and QUIC‑heavy apps—only the payload is HTTPS aimed at OpenAI. Once TUN is reliable, YAML arguments replace superstition about “which terminal forgot its proxy last Tuesday.”
Corporate devices: kernel extensions and enforced VPNs collide with user‑installed TUN adapters. Validate on lab hardware first; this article explains transport mechanics, not your employer’s acceptable use policy.
Make TUN the default plane for Codex and its toolchain
Install a maintained Meta‑class GUI such as Clash Verge Rev, enable its Windows service or macOS network extension, then flip TUN on with a stack you can justify—system when you want the host kernel to own the interface, gvisor when another security product demands user‑space isolation. Trade‑offs live in our gvisor versus system stack comparison. Pick one, document it for teammates, and resist the temptation to toggle stacks every time latency jitters.
After TUN comes up, validate capture with a deliberately boring probe: curl -I https://api.openai.com from the same session that launches Codex CLI. If handshake duration collapses relative to a no‑proxy baseline, you have evidence that exit policy is doing real work. If requests fail instantly, rotate through subscription nodes that tolerate modern TLS before you open tickets about GPT‑5.x reliability. Remember that WSL2 guests do not automatically inherit Windows TUN; bridge mixed ports inward or run Clash inside Linux when your repositories live entirely in that namespace.
Step‑by‑step: from noisy timeouts to predictable OpenAI routing
Treat the list below as an operations checklist you can paste into incident runbooks when someone insists they “already had Clash working in Chrome.”
- Reproduce without Clash: measure baseline latency and determine whether failures are connection timeouts instead of HTTP errors. Identical failure modes usually mean ISP or upstream issues, not YAML.
- Enable TUN and pause competing VPNs: confirm the virtual adapter exists and Clash logs show inbound SYNs that correspond to terminal activity.
- Add OpenAI‑oriented rules above catch‑alls: minimally suffix coverage for
openai.comandchatgpt.com—replace placeholder group labels with your real outbound group name. - Reload the profile and retry login: watch SNIs during browser OAuth; stray marketing domains should not pin themselves to
DIRECTif policy forbids it. - Align DNS: configure
nameserver-policywhen public resolvers poison critical suffixes; expandfake-ip-filterwhen LAN or console hosts must bypass synthetic answers. - Stress streaming jobs: run multi‑minute Codex sessions with large diffs; compare retry counters before and after edits.
YAML you can defend in an architecture review
Remote rule providers are seductive until Tuesday’s update shuffles ordering and Codex CLI suddenly matches a blunt GEOIP,CN,DIRECT line. Maintain a compact local block for AI vendors even if you love community lists—explicit suffix lines beat hours of theorizing about model meltdowns. Illustrative structure:
# Local OpenAI routing block — rename AI-Outbound to match your profile
DOMAIN-SUFFIX,chatgpt.com,AI-Outbound
DOMAIN-SUFFIX,openai.com,AI-Outbound
# Optional explicit splits when you meter marketing differently from API:
# DOMAIN,platform.openai.com,AI-Docs
# DOMAIN,api.openai.com,AI-API
Place those entries below RFC1918 bypasses and above broad MATCH or GEOIP catch‑alls. If you ingest third‑party lists, read the ACL4SSR versus Loyalsoldier comparison so you understand whether “AI” coverage is genuine or aspirational. After every edit, preview the first matching rule for a synthetic URL inside the Clash UI—surprises belong in staging, not in a midnight support thread.
Proxy groups: prioritize steady streams over leaderboard screenshots
Latency leaderboards rarely predict how gracefully a node carries sixty seconds of sustained upstream upload—the exact shape of Codex usage when it streams rationale tokens while also shipping repository mutations. Configure url-test or fallback groups with health checks that mirror HTTPS realities, label servers with honest geography, and avoid obsessive node hopping if your provider’s NAT mappings flap during peak evening hours. Where possible, pair outbound probes with long synthetic streams so you detect middleboxes that only wake up after idle intervals.
DNS, FakeIP, and the illusion of random Codex failures
FakeIP hands Clash synthetic answers that keep policy close to the dataplane, yet it punishes sloppy fake-ip-filter maintenance. If your shell asks a public resolver for api.openai.com while Clash assumes another pathway, you can hit the wrong outbound, observe RST storms, or succeed once per boot until caches diverge. Read Meta core DNS leak prevention before flipping obscure knobs. The workflow that saves weekends is simple: for every stubborn timeout, log hostname, resolver IP, and the first policy Clash assigns to the SYN—when those disagree, fix DNS before rewriting prompts.
The same discipline keeps auxiliary tools honest. When Codex calls MCP servers or local inspectors alongside remote models, mixed localhost and cloud traffic amplifies resolver mistakes—tight YAML plus observant logging is cheaper than mystical reboots.
Sniffer optional: Clash Meta’s Sniffer can rebuild domains when HTTPS alone is too coarse, but it changes your threat model. Start without it when suffix rules already align with logs.
Verification rituals you can repeat at 2 a.m.
Checklists outperform vibes. After every profile edit, reload Clash, tail logs, run two curls from Terminal, launch Codex CLI, and confirm whether OAuth completes without an extra browser refresh. Regressions warrant rolling back the last YAML chunk instead of stacking speculative tweaks. Long jobs deserve their own validation pass because some carriers only reveal bufferbloat after a sustained upload—the same pattern coding agents trigger while emitting large patches.
- Log discipline: filter for
api.openai.com,chatgpt.com, and the outbound you expect; bursts of SYN retransmits scream path problems, not model quality. - DNS cross‑check: compare resolver traces with Clash DNS logging whenever FakeIP is active.
- Rollback proof: disabling TUN should restore baseline routing without rebooting; if not, remove duplicate routes introduced during experiments.
FAQ
Why does Codex CLI time out while ChatGPT in Chrome is instant?
Browsers consume the system proxy table; many CLIs ignore it unless you export environment variables for every subprocess. TUN routes both uniformly so split routing executes before worker quirks surface.
Is HTTP_PROXY enough on its own?
Often for quick tests, yet helper processes, HTTP/3 stacks, or fresh shells routinely bypass classic CONNECT proxies. For multi‑binary agents, TUN is the low‑surprise baseline.
Which OpenAI domains deserve explicit rules?
Begin with suffix coverage for openai.com and chatgpt.com, then refine with log‑sourced DOMAIN lines if you meter docs separately from API traffic. CDN edges evolve—trust your captures, not forum screenshots from last year.
Does WSL2 require a different recipe?
Yes. Treat the Linux NIC as a first‑class citizen: forward mixed ports from Windows, or run a Clash instance with Linux TUN inside WSL so npm, git, and Codex share the namespace that your YAML describes.
Tradeoffs and honest limits
Routing overseas for research convenience can collide with data residency expectations; document which payloads leave the network and why. Aggressive DIRECT optimizations can accelerate domestic CDNs yet strand OpenAI traffic on congested peering the moment an international cable garners headlines. Budget quarterly YAML audits beside API key hygiene so Codex CLI reliability stays boring instead of theatrical.
Clash cannot cure genuine upstream saturation, buggy client releases, or last‑mile bufferbloat. It can stop you from pinning long completions to paths your carrier treats as scavenger class, and it can eliminate the failure mode where the browser tab succeeded because it used TUN while the terminal did not.
Closing thoughts
OpenAI Codex is a product story about GPT‑5.x class assistance, yet the tickets that flood issue trackers are frequently quiet TCP narratives. Putting the Codex CLI on the same Meta dataplane as the rest of the OS—especially via TUN—converts “mystery timeout” into log lines you can filter. Pair explicit suffix rules with conservative DNS policy, validate streaming workloads instead of one‑shot pings, and keep local YAML fragments you can paste into design reviews without embarrassment.
Many proxy utilities either force all traffic through a single tunnel with no fine‑grained control or scatter half‑edited snippets across machines without a coherent UI story. Clash keeps vendor‑aware split routing inside one profile, offers TUN when binaries refuse classic proxies, and documents DNS behavior well enough to reduce FakeIP whiplash. If you are still blaming the model whenever OpenAI Codex wheezes, download Clash, walk through the steps above, and let your terminal finally agree with the browser about how it reaches OpenAI.