Desktop: config.toml zero-filled to NUL bytes after ungraceful shutdown — non-atomic write on Windows loses entire file content
Summary
Codex Desktop on Windows writes ~/.codex/config.toml non-atomically and without FlushFileBuffers. If the OS loses power (or is force-rebooted) between the moment Codex's write() returns and the moment NTFS flushes the dirty page cache to disk, NTFS commits the file's new size to the directory metadata but never writes the data clusters. Per the file-system's zero-fill-on-read security policy, the file then reads as uniform 0x00 bytes from byte 0 to EOF, blowing away every user customization (plugins, MCP servers, sandbox mode, model settings, trusted projects).
On next launch Codex bails with:
failed to load configuration: C:\Users\<user>\.codex\config.toml:1:<size+1>: key with no value, expected `=`
because the TOML parser walks N NUL bytes as one runaway bare key and hits EOF without finding =.
Reproduction
- On Windows 10/11, launch Codex Desktop and let it write
config.toml(any settings change, plugin install, or[projects.*]trust prompt will do). - Within ~30s of the write — before Windows' lazy writeback flushes the page cache — cut power (or hold the power button until the machine shuts down hard).
- Boot back up, launch Codex Desktop.
- Expected: previous config loads, or Codex falls back to defaults cleanly.
- Actual:
~/.codex/config.tomlisNbytes of0x00. Codex refuses to start with the parse error above. The "Use backup sandbox" button doesn't fix it because that only swaps sandbox mode — the parser fails before sandbox setup even runs.
Forensic evidence from one occurrence
File: C:\Users\<user>\.codex\config.toml
Size: 4183 bytes
First 16 bytes: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Last 16 bytes: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
LF count: 0
CR count: 0
NUL count: 4183
Unique byte values across whole file: { 0x00 }
File mtime matched the user's last Codex action ~5 minutes before the power loss. Three sibling files in .codex/ (AGENTS.md, auth.json, chrome-native-hosts-v2.json) were untouched by the same crash window because they hadn't been re-written that session — they survived intact.
Root cause
This is the classic ext4 zero-after-crash pattern, just on NTFS. Codex's persistence path appears to be a straight open(path, O_TRUNC) → write() → close(), without:
- writing to a temp file (
config.toml.tmp), FlushFileBuffers(handle)to force the dirty cache to disk,MoveFileEx(tmp, dst, MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING)for atomic replace.
Without these, the durability guarantee Codex appears to depend on doesn't exist on Windows.
Suggested fix
Adopt write-temp-then-rename atomic semantics for config.toml (and any other crash-critical files in ~/.codex/, e.g. auth.json, .codex-global-state.json, chrome-native-hosts-v2.json):
// pseudocode
let tmp = path.with_extension("toml.tmp");
{
let mut f = File::create(&tmp)?;
f.write_all(contents.as_bytes())?;
f.sync_all()?; // FlushFileBuffers under the hood on Windows
}
// On Windows: MoveFileExW(tmp, path, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)
// On POSIX: rename(tmp, path)
fs::rename(tmp, path)?;
This makes the worst possible crash leave either the old intact file or the new intact file on disk — never a zero-filled phantom.
Secondary observation (separate, possibly related)
When a user hits this and clicks "Use backup sandbox", Codex tries to set up the elevated admin sandbox, which on some machines fails with "Couldn't set up admin sandbox" (see #14808, #23249). That makes the "Use backup sandbox" recovery path effectively a dead end for affected users — they have to fix the config file manually before Codex will boot at all.
Workaround for currently-affected users
- Move the zeroed file aside:
Move-Item ~/.codex/config.toml ~/.codex/config.toml.corrupt - If you've ever shared a session that included a
Get-Content config.tomlagent call, your old config may be recoverable from the JSONL rollout file. - Otherwise: start Codex with an empty config, set
[windows] sandbox = "unelevated"if you hit the secondary sandbox bug, re-trust your projects on demand.
Environment
- OS: Windows 11 Pro 10.0.26200
- Codex Desktop: latest as of 2026-06-04
- Reproduction trigger: power loss during a Codex session
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗