Skip to content

Windows elevated sandbox: detached ReadAclsOnly codex-windows-sandbox-setup.exe helpers never exit after completing their work — each busy-spins ~25% of a core and they accumulate per command #32194

Description

@clusteruni-debug

What version of Codex CLI is running?

0.144.1 (npm @openai/codex; current latest at time of filing)

What subscription do you have?

ChatGPT (OAuth sign-in) — the bug is plan-independent

Which model were you using?

gpt-5.6 family (model-independent)

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64 (Windows 11 Home)

What terminal emulator and version are you using (if applicable)?

Reproduces in both Windows PowerShell 5.1 console and node-pty (ConPTY) panes — not terminal-specific

Codex doctor report

not available (omitted: local paths contain PII; happy to provide sanitized excerpts on request)

What issue are you seeing?

With [windows] sandbox = "elevated" and sandbox_mode = "workspace-write", the detached ReadAclsOnly codex-windows-sandbox-setup.exe helpers complete their work within ~1 second but never exit — each keeps busy-spinning at ~25-30% of one core until manually killed. They accumulate for the life of a codex session and survive the parent codex.exe exiting (orphans keep spinning).

Observed scale: 46 concurrent instances = 2.6 cores on a 16-core machine (measured via 4-second TotalProcessorTime delta sampling); with two interactive sessions active, new instances appeared roughly once per minute. CPU accrues linearly from birth for every instance, e.g.:

pid born 15:20:34Z -> 178.6 CPU-sec at age 9.8 min (~0.30 core)
pid born 15:22:17Z -> 124.5 CPU-sec at age 8.1 min (~0.26 core)
pid born 15:25:00Z ->  65.5 CPU-sec at age 5.4 min (~0.20 core)

Evidence the work completes but the process does not exit — from $CODEX_HOME/.sandbox/sandbox.<date>.log (single day):

Where this appears to come from in source (checked at tag rust-v0.144.1, identical on main):

  1. require_logon_sandbox_creds (codex-rs/windows-sandbox-rs/src/identity.rs, comment "Always refresh ACLs (non-elevated) for current roots via the setup binary") runs the setup exe on every elevated creds acquisition — i.e. per command.
  2. Each run reaches run_setup_full (setup_main/win.rs) → spawn_read_acl_helper: the helper re-spawns itself detached with mode = ReadAclsOnly (fire-and-forget Command::spawn(), CREATE_NO_WINDOW, stdio null). Nothing ever waits on it or kills it.
  3. Dedup relies on the named mutex Local\CodexSandboxReadAclLocal\ is per-logon-session, there is a check-then-spawn race, and on a mutex-check error it spawns anyway, so instances can stack.
  4. Whatever the ReadAclsOnly process does after logging read ACL run completed never returns — externally it looks like a busy-wait in the exit/teardown path (exact loop not identified from outside).

Impact: any long interactive codex session slowly eats the machine — multi-core sustained burn plus dozens of ~10 MB processes — and the cost persists after codex exits because orphans keep spinning.

What did you expect to happen?

The ReadAclsOnly helper exits once its run completes (the completion log line already exists); helpers do not outlive their session; idle helpers do not pin CPU.

Steps to reproduce

  1. Windows 11, [windows] sandbox = "elevated" (setup completed previously), sandbox_mode = "workspace-write".
  2. Run an interactive codex session and let it execute a handful of sandboxed commands.
  3. Watch Get-Process codex-windows-sandbox-setup | Select-Object Id, StartTime, @{n='cpu';e={$_.TotalProcessorTime}} — instances accumulate with steadily growing CPU and persist after the session (and parent process) exits.

Workaround

Killing the helpers is safe in practice (idempotent one-shot ACL applier; the next per-command refresh re-applies anything unfinished): we run a periodic sweep killing instances that are orphaned or older than 5 minutes — 60+ kills so far with zero codex-session breakage. Switching [windows] sandbox = "unelevated" also avoids the issue entirely (that path never spawns the helper), at the cost of the weaker sandbox.

Related-but-different issues (none describes the never-exits/busy-spin behavior): #29938 (proxy-port marker loop), #31556 (WFP re-arm loop), #31605 (recursive profile re-ACL scope).

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingperformancesandboxIssues related to permissions or sandboxingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions