Windows Desktop: switching Agent environment to WSL2 fails startup with state db backfill handshake timeout
What version of the Codex App are you using (From “About Codex” dialog)?
- MSIX package:
OpenAI.Codex_26.727.4816.0_x64 - Desktop build observed in logs / MCP env:
26.727.40816/ package26.727.4816.0 - WSL-side CLI available:
codex-cli 0.146.0
What subscription do you have?
ChatGPT Pro (desktop signed in)
What platform is your computer?
- Windows 11 25H2, build
26200, x64 - WSL2 distro:
Ubuntu-24.04(default, Running) - WSL kernel:
6.18.33.2-microsoft-standard-WSL2 - Windows user:
Lenovo - WSL user:
xdreamer(/home/xdreamer)
What issue are you seeing?
After changing Settings → Agent environment from Windows native to WSL2 / Windows Subsystem for Linux, Codex Desktop fails to start and shows:
ChatGPT failed to start.
Codex app-server initialize handshake timed out
Desktop logs show the app-server is launched inside WSL, then blocks on a state DB backfill from the Windows Codex home mounted at /mnt/c/..., and the Desktop 30s initialize handshake times out.
Sanitized Desktop log excerpt:
[wsl] eligible distro list listResult="NAME STATE VERSION\n* Ubuntu-24.04 Running 2"
[spawn-async] Spawning process inside WSL
[StdioConnection] stdio_transport_spawned
executablePath=C:\Users\<user>\.codex\bin\wsl\<hash>\codex
spawnCommand=wsl.exe
[AppServerConnection] Transport start success transport=stdio
[AppServerConnection] Initialize handshake still pending
connectionError={"code":"connection-failed","message":"state db backfill is running at /mnt/c/Users/<user>/.codex; waiting up to 30s before retrying startup initialization"}
durationMs=30011
initialize_handshake_result outcome=failure
errorMessage="Codex app-server initialize handshake timed out"
app_server_connection.closed code=1
reason="Error: failed to initialize sqlite state runtime under /home/<wsl-user>/.codex/sqlite: timed out waiting for state db backfill at /mnt/c/Users/<user>/.codex after 30s (status: running)"
Desktop bootstrap failed to start the main app phase=bootstrap-import-main
Important recovery detail:
%USERPROFILE%\.codex\.codex-global-state.jsonhad"runCodexInWindowsSubsystemForLinux": false- but
%USERPROFILE%\.codex\config.tomlstill had:
[desktop]
runCodexInWindowsSubsystemForLinux = true
Desktop continued spawning WSL until config.toml was set to false. After that:
stdio_transport_spawned executablePath=...\WindowsApps\OpenAI.Codex_...\app\resources\codex.exe
initialize_handshake_result durationMs=225 outcome=success
So WSL mode left the app unlaunchable, and the dual config sources made recovery non-obvious.
What steps can reproduce the bug?
- Use Codex Desktop on Windows with an existing local profile under
%USERPROFILE%\.codex. - Ensure WSL2 is installed with a default Ubuntu distro that is eligible (
wsl -l -vshows Running / Stopped version 2). - Open Codex Desktop in Windows native mode (works).
- Go to Settings and switch Agent environment to WSL / Windows Subsystem for Linux.
- Quit and relaunch Codex Desktop.
- Observe the fatal dialog:
Codex app-server initialize handshake timed out
- Inspect Desktop logs and observe WSL spawn + 30s state db backfill timeout from
/mnt/c/Users/<user>/.codexinto/home/<wsl-user>/.codex/sqlite. - Set
[desktop] runCodexInWindowsSubsystemForLinux = falsein%USERPROFILE%\.codex\config.tomland relaunch. - Observe Windows-native
codex.exespawn and a successful handshake in a few hundred ms.
Local size context (not multi-GB session history)
At failure time, approximate sizes under %USERPROFILE%\.codex:
logs_2.sqlite ~438 MB
logs_2.sqlite-wal ~14 MB
state_5.sqlite ~1.7 MB
sessions ~645 MB (127 files)
archived_sessions ~103 MB (137 files)
This is much smaller than the multi-tens-of-GiB history case in #35674, but still enough for WSL-mode startup backfill over /mnt/c to exceed the fixed 30s Desktop handshake budget.
There was also a non-fatal warning while launching WSL mode:
bundled_executable_relocation_failed
executableName=bwrap
sourcePath=...\app\resources\codex-resources\bwrap
ENOENT
That appears secondary; the fatal path is the state db backfill timeout.
What is the expected behavior?
- Switching Agent environment to WSL2 should either:
- complete first-run / state backfill successfully, or
- open the app with a progress/recovery UI instead of a fatal handshake timeout.
- State DB backfill / SQLite init performed over
/mnt/cshould not be on a hard 30s critical path that prevents Desktop bootstrap. - If WSL mode fails, Desktop should provide a one-click fallback to Windows native mode without requiring manual edits of config files.
runCodexInWindowsSubsystemForLinuxshould have a single source of truth. Having.codex-global-state.jsonsayfalsewhileconfig.toml [desktop]still saystrue(and Desktop obeys the latter) makes recovery confusing when the app cannot open Settings.- Diagnostic logs / DB maintenance should not block app launch; if backfill is required, it should be resumable and backgrounded.
Additional information
Related issues (same failure family, different emphasis):
- #35674 — large long-lived session history blocks startup during state DB backfill
- #27741 — large
logs_2.sqlitecauses startup SQLite/pool timeout (often under WSL/mnt/c) - #32902 — WSL switch fails during provisioning / history display issues
- #28087 — stuck on sqlite state backfill
- #17254 / older WSL agent mode startup failures
This report is specifically about:
- Agent environment → WSL2 as the trigger
- Desktop spawning WSL app-server
- fatal
state db backfill ... after 30sduring initialize handshake - dual config sources (
config.tomlvs.codex-global-state.json) complicating recovery
Workaround that restored launch on this machine:
# %USERPROFILE%\.codex\config.toml
[desktop]
runCodexInWindowsSubsystemForLinux = false
I can provide additional sanitized Desktop log excerpts if useful. I am not attaching raw session JSONL / auth / full SQLite dumps because they contain local paths and conversation content.
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Additional reproduction on NixOS WSL2, with a non-destructive recovery
I reproduced this on a current Desktop build with NixOS as the WSL2 distribution. This adds two useful findings:
Environment
OpenAI.Codex_26.727.6591.0_x640.146.0-alpha.9.2262006.18.33.2-microsoft-standard-WSL226.11.20260729.0954f7eWhat happened
The Desktop successfully discovered NixOS and spawned the relocated Linux binary through
wsl.exe:The actual WSL process was alive with valid stdin/stdout pipes, a valid working directory, the expected
HOME, and the intended split state paths:At exactly 30 seconds, Desktop failed the bootstrap:
However, the app-server process remained alive and continued building:
The source Windows
state_5.sqlitewas approximately 125.2 MB. During the failed launch, the WSL-local database grew continuously to approximately 122.8 MB plus its WAL. At about 69 seconds after spawn, itsbackfill_statechanged to:It contained:
PRAGMA quick_check(1) = okThe transport stopped shortly after the backfill reached
complete.Non-destructive recovery observed
I then relaunched Desktop without changing configuration, deleting data, reinstalling, or shutting down WSL. The same WSL backend initialized successfully:
For a profile of this size, the effective workaround was therefore:
This is much safer than deleting SQLite state or moving session history, although it may not work for very large profiles if Desktop terminates the backfill before it can complete.
NixOS and
bwrapfindingsThe preliminary suspicion that this was a NixOS launch/shell problem was ruled out:
/usr/bin/bashworked.Desktop also logged the known warning that its packaged
codex-resources/bwrapwas absent. NixOS supplied/run/current-system/sw/bin/bwrap, and the second launch succeeded despite the same relocation warning, so that warning was not causal here.Suggested fix
The state migration/backfill should not share a fatal 30-second deadline with the app-server protocol handshake. Possible approaches:
complete; orThe key evidence here is that the supposedly failed app-server was healthy and made measurable progress, and the exact same backend initialized in 2.826 seconds once its one-time WSL-local backfill had completed.
nice issue!
Having this issue too.