Windows sandbox: `SetTokenInformation(TokenDefaultDacl) failed: 1344` (ERROR_ALLOTTED_SPACE_EXCEEDED) — every command fails before start in workspace-write, on both elevated and unelevated
Related: #9062, #16780 (same "command-runner fails before process start in workspace-write on Windows" family, but a different error code — 1344, not 1385).
Summary
On Windows, with sandbox_mode = "workspace-write", every model-issued shell command fails before the process starts with:
ERROR codex_core::exec: exec error: windows sandbox: runner error: SetTokenInformation(TokenDefaultDacl) failed: 1344
exited -1 in 0ms
1344 = ERROR_ALLOTTED_SPACE_EXCEEDED ("No more memory is available for security information updates"): the default DACL being applied to the restricted token exceeds the token's allotted default-DACL space.
Environment
- Codex CLI 0.137.0 (npm
@openai/codex), Node v25.9.0, npm 11.12.1 - Windows 11 Pro 10.0.26200 x64, OS language es-MX (localized profile)
- User profile path contains a space:
C:\Users\Ignacio Villanueva - Localized legacy junctions in the profile (
Configuración local,Datos de programa,Menú Inicio,Reciente,SendTo,Plantillas, etc.) - Session: Medium integrity, non-elevated (Administrators present but "deny only")
- Config:
sandbox_mode = "workspace-write",[windows] sandbox = "elevated"
Minimal repro
codex exec --skip-git-repo-check -c approval_policy=never "Run Get-Location once."
→ exited -1 in 0ms, error 1344. The command it tried to run was pwsh.exe -Command Get-Location — it never reaches PowerShell.
Isolation matrix (all from cwd = user home)
| Mode | Result |
|------|--------|
| workspace-write, windows.sandbox = elevated | ❌ FAIL 1344 |
| workspace-write, windows.sandbox = unelevated | ❌ FAIL 1344 (so it's not elevation-specific) |
| read-only | ✅ OK |
| danger-full-access | ✅ OK |
| codex sandbox <cmd> subcommand (runs read-only) | ✅ OK |
The failure is specific to building the writable default DACL for workspace-write. Read-only never builds it; full-access uses no restricted token. Running an elevated terminal (Administrator) does not fix it — fails identically.
Logs
~/.codex/.sandbox/sandbox.YYYY-MM-DD.log shows the setup binary completing fine:
setup refresh: processed 121 write roots (read roots delegated); errors=[]
codex-windows-sandbox-setup.exe: setup binary completed
START: ...pwsh.exe -Command Get-Location
…then the runner fails at token creation (1344). Note 121 write roots — on a localized (es-MX) profile the duplicated legacy junction folders inflate the write root set, which I suspect overflows the token's default-DACL allotted space.
Suspected root cause
When the command-runner constructs the restricted token's default DACL for workspace-write, the ACE set (one per write root × the inflated localized-profile roots) exceeds the token default-DACL allotted space → ERROR_ALLOTTED_SPACE_EXCEEDED (1344). Likely reproducible on any non-English / localized Windows profile, and cwd-independent (fails the same from a no-space path like C:\tmp\codex-test).
Workarounds (for other users hitting this)
-s read-only(loses write) or--dangerously-bypass-approvals-and-sandbox(no sandbox).- Switching elevated ↔ unelevated does not help.
5 Comments
same issue. any progress
Confirming this on a zh-CN (Chinese) localized Windows profile — a second non-English profile data point that supports the "localized legacy junctions inflate the write-root set" root cause.
Environment
@openai/codex,codex-win32-x64) — so still not fixed as of latest stable (original report was 0.137.0)config.toml:[windows] sandbox = "unelevated"Same failure, same isolation matrix (verbatim match)
| Mode | Result |
|---|---|
|
workspace-write(unelevated) | ❌ FAIL 1344 ||
read-only| ✅ OK ||
danger-full-access| ✅ OK ||
codex sandbox <cmd>(standalone) | ✅ OK |Extra data point: it's not just
shell_command— the whole workspace-write execution layer is downIn a single
workspace-writeturn, all three execution channels failed with the same 1344 (raw--jsonevents):apply_patchto both the workspace (C:\Users\<user>\...) andC:\tmp\...also failed with the same underlying error (C:\tmpexists — not a missing-path issue).Localized-junction evidence (supports the es-MX theory)
This zh-CN profile carries 11 legacy compatibility junctions in the user home that expand the write-root set:
net helpmsg 1344on this machine returns "No more memory is available for security information updates." =ERROR_ALLOTTED_SPACE_EXCEEDED, consistent with the writable default-DACL's ACE set overflowing the token's allotted default-DACL space when workspace-write enumerates the (junction-inflated) write roots.Takeaway
Reproduces identically on a second, unrelated localized profile (zh-CN), on the latest stable 0.142.5, on a non-admin CloudAP account. Strongly points at write-root/DACL-size overflow rather than anything account-specific. Only viable workaround remains
sandbox_mode = "danger-full-access"(loses all fs/network sandboxing).Root-cause data from an independent reproduction — including a controlled differential and a security-descriptor analysis that narrows the mechanism. Three findings that update the current working theory:
1. Not localization-specific — and not "every command": it is the profile root as cwd, exactly
Reproduces on an en-US, non-localized profile (Codex CLI 0.144.5, Windows 11 Pro 10.0.26200,
[windows] sandbox = "unelevated", medium-integrity interactive session), so localized legacy junctions are not the necessary condition.Controlled 5-cell differential, single variable = cwd, same command (
codex exec --skip-git-repo-check -c approval_policy=never "Run: echo OK"):| cwd | sandbox | result |
|---|---|---|
|
C:\Users\<user>(profile root) | workspace-write | 1344 || project subdir of profile | workspace-write | OK (~380ms) |
| fresh empty subdir of the profile | workspace-write | OK ← decisive |
| unregistered temp dir | workspace-write | OK |
|
C:\Users\<user>(profile root) | read-only | OK |So "every command fails" in the original reports fits users who launch codex from
~(very common for a global CLI). Any other working directory — even a brand-new empty subdirectory of the same profile — is fine, and--sandbox read-onlyis cwd-agnostic (consistent with the failing call being the writable-root default-DACL setup). Reboot does not change any cell (verified before/after a full Windows update + restart).2. Descriptor differential: the profile root's unique feature is a 56-byte non-inheriting capability-SID ACE
Comparing
Get-AclSDDL for the failing root vs. two working subdirs, the only trustee present on the root and absent from every working control is:— a 10-subauthority capability SID (48-byte SID → 56-byte ACE), allowing Traverse+Synchronize, no OI/CI flags. Being non-inheriting is exactly why a fresh subdir of the same profile works: children never receive it. (Ordinary trustees — SYSTEM/Administrators/user/CodexSandboxUsers — are identical across all three DACLs.)
3. Mechanism: pre-allotted token default-DACL storage, not on-disk DACL size
Per Microsoft's
ZwSetInformationTokendocs,STATUS_ALLOTTED_SPACE_EXCEEDED(Win32 1344) forTokenDefaultDaclmeans the token's pre-allotted default-DACL/primary-group storage cannot accept the new value. Decoded byte math (matches .NETRawAcl.BinaryLengthexactly):| directory | DACL bytes |
|---|---:|
| profile root (FAILS) | 180 |
| working subdir A | 160 |
| working subdir B (WORKS) | 232 |
A working directory's DACL is larger than the failing root's — so this is not raw descriptor size. The evidence points at the derivation path: when workspace-write builds the restricted token's default DACL from the cwd's descriptor, the oversized capability ACE (20 bytes larger than a normal-SID ACE) either crosses the token's default-DACL allotment or trips an ACE-size assumption sized for conventional 28-byte SIDs. Suggested fix direction: filter capability SIDs (
S-1-15-3-*) out of the derived default DACL, or size the buffer from the actual ACEs being carried.Workarounds validated (all cells reproducible)
cdinto any real working directory before invoking codex — the complete practical fix.--sandbox read-onlyfor read-only tasks works from anywhere.[windows] sandbox = "elevated"is not a workaround here: it trades 1344 for os error 206 (the CreateProcessW payload limit — #32315).Happy to provide the full SDDL captures if useful.
Root-caused this on an affected profile and have a working fix + tests.
Why 1344 happens:
create_token_with_caps_from(codex-rs/windows-sandbox-rs/src/token.rs) builds the restricted token's default DACL with one ACE per capability SID, and there is one capability SIDper write root.
SetTokenInformation(TokenDefaultDacl)replaces the DACL in place, and the replacement must fit the space allotted when the token was created (sized from the base token's typically tinydefault DACL). Running from a directory with many write roots (home directory; localized profiles with duplicated legacy junctions as noted above) yields hundreds of capability SIDs → the DACL no longer
fits →
ERROR_ALLOTTED_SPACE_EXCEEDED (1344)before every spawn.Why affected profiles accumulate deny ACEs:
cap_sidis persisted non-atomically from concurrent load-modify-persist sequences (per-session setup refresh, world-writable audit). A torn read makeshelpers regenerate random capability SIDs and drop entries, and deny ACEs for stale SIDs accumulate unboundedly on protected paths like
~/.codex(observed: +2 ACEs every ~5s per running session; ~800ACEs over weeks on one machine). The legacy fallback in
load_or_create_cap_sidsalso treats any non-JSON content (e.g. a torn write) as a bare SID string, scrambling the store further.Working fix branch (with regression test): https://github.com/LCABC777/codex/tree/fix/windows-sandbox-default-dacl-1344
token.rs: onERROR_ALLOTTED_SPACE_EXCEEDED, retry the default DACL with just the logon and Everyone SIDs. Both are also restricting SIDs of the token, so the DACL stays permissive for every processspawned inside the sandbox. Also closes the token handle on the error path.
cap.rs/audit.rs:cap_sidis now persisted atomically (temp file + rename) on all write paths; unrecognized non-JSON content is moved aside tocap_sid.corruptinstead of being reinterpreted asa SID.
workspace_write_token_with_many_capability_sids_succeeds: builds a workspace-write token with 800 capability SIDs — fails with 1344 before the fix, passes after. `cargo test -pcodex-windows-sandbox` is green on Windows 11 (the only failures are pre-existing unified_exec tests that require interactive UAC elevation).
Immediate workaround for affected users: remove the stale deny ACEs (unresolved SIDs) from
~/.codex, or reset the folder ACL to inherited defaults; the 1344 error clears immediately.Happy to open a PR if the team would like to invite one.
Adding datapoints from another Windows 10 machine — same error signature, but
with an important twist: on this machine the failure is exclusive to the
Desktop-packaged host, while the same runtime build works fine when
spawned from the VS Code extension or a plain terminal.
Environment
OpenAI.Codex 26.820.9563.0, in-app build26.820.71523codex-cli 0.150.0-alpha.8sandbox_modetested acrossread-only/workspace-write/danger-full-access;[windows] sandbox = "unelevated"; approvalon-request.codex),unlike some other reports here
What we see
code-mode host exited during handshake. Desktop's own logs show plaingit ... spawn_failedat the same moments.originator=codex_vscode) ran allday without a single failure, including subagent spawns;
codex sandbox cmd /c echo ok) pass under read-only,workspace-write and danger-full-access when run from a normal terminal.
read-onlysessions can executeminimal commands (e.g.
pwdsucceeds);workspace-writefails; notablydanger-full-accessalso fails, suggesting the host dies before/independentof the policy-specific token construction.
09D67239…→799FF771…, code-mode-host3B93FC5D…→F081067C…) withoutbumping the reported version string (still
0.150.0-alpha.8). Firstpost-update Desktop session immediately reproduced the handshake failure,
so build
26.820.71523does not fix it.Interpretation
Since the same sha256 binary succeeds in all three modes outside the packaged
app and fails inside it, this looks less like pure DACL-space arithmetic
(group-SID count) and more like something about the execution context of the
MSIX-packaged app-server / code-mode host interacting with restricted-token
creation. Happy to run any diagnostic (procmon trace,
codex doctoroutput,log excerpts) on request.