Troubleshooting & Diagnostics
codex doctor, logs, sandbox failures, and recovery
- Be able to run `codex doctor` and read its diagnostic report to localize an install, config, auth, runtime, Git, terminal, or app-server problem
- Be able to find Codex state and logs under `CODEX_HOME` (`~/.codex`) and on the macOS Desktop app, and raise log verbosity with `RUST_LOG`
- Be able to diagnose and fix the common Linux/WSL2 'couldn't set up sandbox' failure and explain why macOS rarely hits it
- Be able to recover from auth failures with `codex login status` / `codex login`, and configure corporate TLS with `CODEX_CA_CERTIFICATE` / `SSL_CERT_FILE`
- Be able to apply the everyday recovery patterns (pending approvals, `git status`, Up-arrow prompt recovery, focused new thread, opening the right monorepo directory) and know when to escalate via `/feedback`
When Codex misbehaves — a broken install, a sandbox that won't start, an auth loop, a corporate proxy blocking calls — the fastest path is rarely guessing. This lesson gives you the troubleshooting reflex: run `codex doctor` first, know where state and logs live under `~/.codex`, raise verbosity with `RUST_LOG`, and apply the handful of recovery patterns that fix most day-to-day breakage. Built to be the first place you look when something breaks.
- 1The mental model: diagnose before you guess
- 2Start here: `codex doctor`
- 3Know the map: state and logs under `~/.codex`
- 4Turn up the volume: `RUST_LOG`
- 5The #1 failure: 'couldn't set up sandbox'
- 6Auth recovery and the corporate-TLS gotcha
- 7Everyday recovery patterns
The mental model: diagnose before you guess
When Codex breaks, the instinct is to start changing things — reinstall, flip a flag, paste the error into a search box. Resist it. Codex is a local Rust CLI with a small, knowable state directory, which means almost every failure is localizable before you touch anything.
Fix one habit and most sessions get shorter: codex doctor first, logs second, targeted fix third.
codex doctortells you which layer is broken — install, config, auth, runtime, Git, terminal, app-server, or threads — without you having to reproduce the failure by hand.- The
~/.codexdirectory (overridable viaCODEX_HOME) holds everything stateful: your config, credentials, sessions, and logs. If you know what lives there, you know what to inspect and what to reset. RUST_LOGturns up the verbosity when the report isn't enough, so you see the actual request, sandbox call, or error that failed.
The rest of this lesson is that reflex made concrete: the diagnostic command, the state map, the two or three failure classes you'll actually hit (sandbox, auth, TLS, monorepo), and the cheap recovery moves that beat a reinstall almost every time.
Key insight
Localize, then fix
Most Codex breakage is one of a few classes: install, auth, sandbox, TLS/proxy, or 'wrong directory'. codex doctor plus the ~/.codex state map tells you which class you're in — and the fix follows from the class, not from guessing.
Start here: `codex doctor`
codex doctor generates a local diagnostic report — the single best first move when an install is broken or before you file a support issue. It checks the health of every layer Codex depends on:
- Installation — binary, version, install path
- Configuration —
config.tomlparsing and layering - Authentication — credential state and login method
- Runtime — the sandbox/runtime environment
- Git — repo detection and Git availability
- Terminal — TUI capabilities
- App-server — the local app-server process
- Threads — your session/thread inventory
codex doctor # human-readable report
codex doctor --summary # condensed view
codex doctor --all # run every check, including slower ones
codex doctor --json # redacted, machine-readable report
codex doctor --no-color # plain output (logs, CI)
codex doctor --ascii # ASCII-only outputThe --json form writes a redacted codex-doctor-report.json — safe to share because it strips secrets. That same report is what gets attached when you run /feedback to send logs to the maintainers, so codex doctor --json + /feedback is the standard 'I'm stuck, here's the evidence' escalation path.
| Flag | Use it when |
|---|---|
--summary | You want the headline pass/fail per layer, fast |
--all | A quick run looked clean but something is still wrong |
--json | Sharing with a teammate, attaching to an issue, or scripting checks |
--no-color / --ascii | Piping to a file or a terminal that mangles color/box-drawing |
Read the report top-down and stop at the first failing layer — a broken auth check below a broken install check is usually just a symptom of the install problem.
Tip
Two-command escalation
When you can't fix it yourself: codex doctor --json to produce the redacted report, then /feedback inside the TUI to send it to the maintainers. The report is redacted, so you're not leaking credentials.
Note
Doctor is stable, the rest moves
codex doctor is a stable subcommand, but the exact checks and flags evolve. If a flag here doesn't exist on your build, run codex doctor --help and check the live CLI reference at https://developers.openai.com/codex/cli/reference.
Know the map: state and logs under `~/.codex`
Almost everything Codex persists lives under CODEX_HOME (default ~/.codex). Knowing this map turns 'something is wrong' into 'inspect this file':
| Path | What it holds |
|---|---|
~/.codex/config.toml | Your user configuration (model, approvals, sandbox, MCP, etc.) |
~/.codex/auth.json | Stored credentials / access tokens |
~/.codex/sessions/ | Session transcripts (JSONL rollout files) |
~/.codex/archived_sessions/ | Archived threads |
~/.codex/log/ | CLI logs, e.g. codex-tui.log |
If you've relocated state with CODEX_HOME, substitute that path everywhere above. The macOS Desktop app logs separately, under:
~/Library/Logs/com.openai.codex/YYYY/MM/DDWhen you suspect a layer, go straight to its file: a config that won't parse → config.toml; an auth loop → auth.json (and re-login); a TUI that froze mid-task → ~/.codex/log/codex-tui.log.
A few related env vars are worth knowing because they move this state around: CODEX_HOME relocates the whole directory, and CODEX_SQLITE_HOME points at the SQLite state path. Relocating CODEX_HOME is itself a clean troubleshooting move — point it at a fresh directory to test with a clean slate without destroying your real config.
Watch out
`auth.json` is a real secret
~/.codex/auth.json contains access tokens in plaintext (file-mode storage). Never paste it into chat, an issue, or a screenshot. To share diagnostics, use codex doctor --json — it's redacted by design. To reset auth, prefer codex logout / codex login over hand-editing the file.
Turn up the volume: `RUST_LOG`
When the doctor report and the obvious files aren't enough, raise verbosity. Codex is a Rust program, so it honors the standard RUST_LOG environment variable, and the extra output lands under CODEX_HOME.
# Coarse global level
RUST_LOG=debug codex
# Levels, low to high: error | warn | info | debug | trace
RUST_LOG=trace codex
# Targeted filters — much less noise than global trace
RUST_LOG=codex_core=debug,codex_tui=debug codexPrefer targeted filters (codex_core=debug,codex_tui=debug) over a blanket RUST_LOG=trace. Global trace produces a firehose; scoping to the crates you suspect (core agent logic vs. the terminal UI) keeps the log readable and points you at the real failure faster.
Workflow: set RUST_LOG, reproduce the failure once, then read ~/.codex/log/codex-tui.log (or the level you raised) for the line where it actually broke — a failed request, a sandbox call that was refused, an MCP server that timed out.
Tip
Reproduce small, then read
Don't trawl a 10,000-line log. Set RUST_LOG, trigger the smallest action that fails (one prompt, one command), then open the log and read the last few entries. The failure is almost always near the end.
The #1 failure: 'couldn't set up sandbox'
On Linux and WSL2, the most common error you'll meet is 'couldn't set up sandbox'. Codex enforces its filesystem/network boundary at the OS level, and when the OS can't provide that enforcement, Codex refuses to run rather than run unsandboxed. That refusal is a feature — but it surprises people.
The enforcement mechanism differs by platform:
| Platform | Sandbox mechanism | Common failure |
|---|---|---|
| macOS | Seatbelt (sandbox-exec), built in | Rarely needs setup |
| Linux / WSL2 | bubblewrap (bwrap) + seccomp, with Landlock fallback | Missing/restricted bubblewrap or disabled user namespaces |
| Windows | Native PowerShell sandbox (or use WSL2) | Elevation/profile issues |
On Linux/WSL2, the cause is almost always one of two things: bubblewrap isn't installed, or unprivileged user namespaces are disabled/restricted by the kernel or a hardened host. Fixes, in order:
# 1) Install bubblewrap (Debian/Ubuntu)
sudo apt-get install -y bubblewrap
bwrap --version # confirm it's on PATH
# 2) Make sure unprivileged user namespaces are enabled (the exact
# kernel knob/sysctl varies by distro and hardened-host policy —
# check your distro's docs and the live sandboxing reference)
# 3) Confirm the runtime layer in the doctor report
codex doctor --summary # look at the Runtime / sandbox checkIf you're on a locked-down corporate host where namespaces can't be enabled, your options are to run inside WSL2 (on Windows) or a permitted container, or — only inside an already-hardened VM/container — to bypass the sandbox deliberately. macOS rarely needs any of this: Seatbelt ships with the OS, so a sandbox failure there usually points at a deeper install problem worth a codex doctor run.
Watch out
Don't reach for `--yolo` to 'fix' a sandbox error
--dangerously-bypass-approvals-and-sandbox (alias --yolo) disables both the sandbox and approvals. It is not a fix for a missing sandbox — it removes the protection entirely. Only use it inside a disposable, hardened container/VM where you've accepted the risk. The right fix is usually installing bubblewrap or enabling user namespaces.
Auth recovery and the corporate-TLS gotcha
Two classes of connection failure look similar but have different fixes: auth (Codex doesn't think you're logged in) and TLS (Codex can't trust the connection at all, usually behind a corporate proxy).
Auth recovery. Check state, then re-establish it:
codex login status # exits 0 when logged in
codex login # browser OAuth (default, recommended)
codex login --device-auth # headless / no local browser
codex login --with-api-key # API-key sign-in (key via stdin)
codex logout # clear stored creds, then login freshcodex login status is scriptable — it exits 0 when you're logged in, non-zero otherwise — so it's the right check in CI or a pre-flight script. If login itself loops, the cleanest reset is codex logout followed by codex login, which rewrites ~/.codex/auth.json from scratch.
The corporate-TLS gotcha. On a corporate network that intercepts TLS (a 'man-in-the-middle' proxy with its own root CA), every Codex request can fail with certificate errors even though your login is fine. The fix is to point Codex at your organization's CA bundle:
# Tell Codex which CA bundle to trust (PEM file)
export CODEX_CA_CERTIFICATE=/path/to/corporate-ca.pem
# Or the standard OpenSSL variable, also honored:
export SSL_CERT_FILE=/path/to/corporate-ca.pemIf auth and certificates both look right but calls still fail, suspect the proxy's network rules next — and remember that in workspace-write, outbound network is OFF by default and must be opted into, which is a frequent 'why can't it reach the internet?' red herring.
Example
Triaging a failed request
Calls fail right after launch. Run codex login status — exits 0, so auth is fine. The error mentions a certificate → it's TLS interception: set CODEX_CA_CERTIFICATE to the corporate CA PEM and retry. Still failing with no cert error → check whether the task even needs network and whether the proxy allows the host.
Everyday recovery patterns
Most of the time nothing is 'broken' — a turn went sideways, you cancelled, or Codex loaded the wrong config. These cheap moves fix the common cases without a reinstall:
- Recover a prompt after cancel. Pressed Ctrl+C and lost your carefully-typed prompt? Press Up to bring it back from draft history instead of retyping. (
Ctrl+Ccancels the turn; it does not silently eat your text.) - Check pending approvals. If Codex looks 'stuck', it may simply be waiting on an approval. Look for the approval prompt before assuming a hang.
- Run
git status. Because Codex works through your normal Git workflow and surfaces a transcript of every action,git status(and/diff) is your ground truth for what actually changed — and your rollback path is plain Git (there is no/undo). - Start a focused new thread. A long, tangled session can drift.
/new(fresh conversation, same session) or a newcodexinvocation with a tight prompt often outperforms fighting a confused thread. Session hygiene is troubleshooting. - Open the right directory in a monorepo. Codex loads project config and
AGENTS.mdrelative to where you launch it. If it's ignoring your settings, you're probably in the wrong subdirectory — open the directory that contains the.codexfolder so the right config layer loads.
| Symptom | First move |
|---|---|
| Lost prompt after Ctrl+C | Press Up to recover the draft |
| Codex appears frozen | Look for a pending approval |
| Unsure what changed | git status / /diff (rollback via Git — no /undo) |
| Thread is confused/drifting | /new or a fresh codex with a tight prompt |
| Settings/AGENTS.md ignored | Re-launch from the dir holding .codex |
| Still stuck | codex doctor --json → /feedback |
Key insight
Git is your undo
There is no /undo in Codex. Every action shows up in the transcript and your working tree, so git status, git diff, and git restore/git checkout are the real rollback mechanism. Commit early so you always have a clean point to return to.
Try it: Build your Codex troubleshooting muscle memory
Goal: practice the diagnose-before-guess reflex on a healthy install so it's automatic when something actually breaks. 1) Run the doctor. In any project, run codex doctor, then codex doctor --summary, then codex doctor --json. Open the generated codex-doctor-report.json and confirm it's redacted (no tokens). Note which layers it checks. 2) Map your state. List ~/.codex and identify config.toml, auth.json, sessions/, and log/. (On macOS, also peek at ~/Library/Logs/com.openai.codex/ if you've used the Desktop app.) Do not open or share auth.json. 3) Raise verbosity. Run RUST_LOG=codex_core=debug,codex_tui=debug codex, send one trivial prompt, exit, then open ~/.codex/log/codex-tui.log and read the last few entries — find the line for your prompt. 4) Verify auth state. Run codex login status and check the exit code (echo $? → 0 means logged in). 5) Simulate the monorepo gotcha. Create a nested dir, cd into it, launch codex, and observe that your project .codex/AGENTS.md config doesn't load; then relaunch from the directory that holds .codex and confirm it does. 6) Practice recovery. Start a turn, press Ctrl+C to cancel, then press Up to recover your prompt. 7) Write four lines: which layer would you check first for (a) a parse error, (b) an auth loop, (c) a 'couldn't set up sandbox' error on Linux, and (d) certificate failures behind a corporate proxy — and the one command or env var you'd reach for in each case. This rehearses the exact moves you'll need under pressure.
Key takeaways
- 1Diagnose before guessing: run `codex doctor` first — it reports the health of install, config, auth, runtime, Git, terminal, app-server, and threads; use `--summary`, `--all`, `--json` (redacted), `--no-color`/`--ascii`.
- 2Codex state lives under `CODEX_HOME` (default `~/.codex`): `config.toml`, `auth.json`, `sessions/`, `archived_sessions/`, and `log/` (`codex-tui.log`); the macOS Desktop app logs to `~/Library/Logs/com.openai.codex/YYYY/MM/DD`.
- 3Raise verbosity with `RUST_LOG` (`error|warn|info|debug|trace`); prefer targeted filters like `codex_core=debug,codex_tui=debug` over global `trace`, then read the tail of the log.
- 4Linux/WSL2 'couldn't set up sandbox' is almost always missing/restricted `bubblewrap` or disabled user namespaces; Codex refuses to run unsandboxed rather than drop protection. macOS uses built-in Seatbelt and rarely needs setup — don't 'fix' it with `--yolo`.
- 5Recover auth with `codex login status` (exit 0 = logged in) and `codex logout`/`codex login`; behind a TLS-intercepting proxy, point `CODEX_CA_CERTIFICATE` or `SSL_CERT_FILE` at the corporate CA PEM.
- 6Everyday recovery: press Up to recover a prompt after Ctrl+C, check for pending approvals, use `git status`/`/diff` (rollback via Git — there is no `/undo`), start a focused new thread, and in a monorepo launch from the directory holding `.codex`.
Quiz
Lock in what you learned
Check your understanding
0 / 4 answered
1.An install seems broken and you're not sure which layer is at fault. What's the recommended first move, and what does it give you?
2.On a fresh Linux host, Codex exits with 'couldn't set up sandbox'. What is the most likely cause and correct fix?
3.Behind your company VPN, every Codex request fails with TLS certificate errors, but `codex login status` exits 0. What's the right fix?
4.You pressed Ctrl+C to cancel a turn and want to undo what Codex changed and recover your typed prompt. Which statement is correct?
Go deeper
Hand-picked sources to keep learning
Official troubleshooting guide: common failures, diagnostics, and where to look when something breaks.
Reference for CODEX_HOME, CODEX_CA_CERTIFICATE/SSL_CERT_FILE, and other env vars used in recovery.
Subcommands and flags, including `codex doctor`, `codex login`, and the global flags — the live source of truth.
How the OS-level sandbox works (Seatbelt, bubblewrap) — the background for 'couldn't set up sandbox' failures.
Source, releases, and issue tracker for the Rust CLI; `codex doctor` landed in PR #22336. File issues with a redacted doctor report.
Live roster of in-session commands, including `/feedback`, `/status`, `/new`, and `/diff` used in recovery.