Claude Desktop: cowork VM gvisor auto-recovery causes cascading boot failures requiring full VM reinstall
Bug Description
Claude Desktop's cowork VM has an auto-recovery mechanism that switches networking from vmnet (via "auto" mode) to gvisor when it detects an API reachability failure. This creates a cascading failure that ultimately requires deleting the entire VM bundle:
- The gvisor switch is persisted to
config.json, causing subsequent VM startups to fail at vsock connect - Repeated failed boots and force-kills corrupt the VM image, so even after restoring vmnet networking and resetting EFI state, the guest kernel no longer boots at all
- The only fix is deleting the entire VM bundle and letting the app re-download from scratch (~10 GB)
Environment
- App version: 1.1.2685
- Platform: macOS 26.2.0 (Darwin 25.2.0), Apple M4 Pro, arm64
- Network mode before failure:
auto(vmnet, working perfectly) - Network mode after failure:
gvisor(VM boots at hypervisor level but guest never connects via vsock)
Root Cause Analysis
Phase 1: gvisor auto-recovery breaks networking
On Feb 9, a momentary API reachability failure triggered the auto-recovery code:
// Triggered by Go.on("apiReachability", ...) when status === "UNREACHABLE"
if (Qr && _w() !== "gvisor") {
vq("gvisor"); // permanently persists to config.json
// restarts VM in gvisor mode
}
This permanently set "coworkNetworkMode": "gvisor" in config.json. All subsequent boots used gvisor and failed at guest_vsock_connect with 60-second timeouts.
Phase 2: Repeated force-kills corrupt the VM
Each failed boot attempt follows this pattern:
- VM boots at hypervisor level (
vm_boot completed) - Guest never connects via vsock (60s timeout)
- VM is force-stopped:
"Timeout waiting for VM to stop (state: 1), proceeding with cleanup"
After 5+ force-kills across Feb 10-11, the VM became permanently broken. The guest kernel no longer produces any output at all:
coworkd.lognot updated (guest daemon never starts)console_tail: undefined(no console output from hvc0)kernel_console_tail: undefined(no kernel boot messages from hvc1)
Phase 3: Neither config fix nor EFI reset resolves it
We attempted the following fixes in order — none worked:
- Restored
"coworkNetworkMode": "auto"— vmnet networking was established correctly (bridge100 up at 192.168.64.1), but guest still didn't boot - Deleted
efivars.fdto reset EFI/GRUB state — fresh EFI vars were created on next boot, but guest kernel still produced zero output - Deleted entire VM bundle (
~/Library/Application Support/Claude/vm_bundles/claudevm.bundle/) — this was the only fix, forcing a fresh ~10 GB download
Why the rootfs corruption isn't detected
The app skips on-disk integrity checks for the rootfs:
[VM:integrity] Rootfs is compressed — checksum is for compressed form, skipping on-disk integrity check
The checksum was only validated against the compressed .zst file during the original download. After repeated force-kills corrupted the on-disk image, there was no mechanism to detect or repair it.
Timeline
| Date | Time | Mode | Result |
|------|------|------|--------|
| Feb 5 | 13:48 | auto (vmnet) | Boot in 13.6s |
| Feb 9 | 15:40 | auto (vmnet) | Boot successful |
| Feb 9 | 15:41 | gvisor (auto-switched) | Boot OK this one time |
| Feb 10 | 13:23 | gvisor | Last successful coworkd activity |
| Feb 10 | 18:45 | gvisor | Timeout — force killed |
| Feb 10 | 18:59 | gvisor | Timeout — force killed |
| Feb 11 | 10:09 | gvisor | Timeout — force killed |
| Feb 11 | 10:11 | gvisor | Timeout — force killed |
| Feb 11 | 10:13 | gvisor | Timeout — force killed |
| Feb 11 | 10:22 | auto (vmnet, config fixed) | Timeout — guest kernel dead |
| Feb 11 | 10:27 | auto (vmnet, efivars deleted) | Timeout — guest kernel still dead |
| Feb 11 | 10:29 | — | Deleted entire VM bundle |
Workaround
Delete the entire VM bundle and relaunch Claude Desktop:
rm -rf ~/Library/Application\ Support/Claude/vm_bundles/claudevm.bundle/
Also ensure the network mode is reset:
# In ~/Library/Application Support/Claude/config.json
# Change "coworkNetworkMode": "gvisor" to "coworkNetworkMode": "auto"
The app will re-download the rootfs (~10 GB) and create fresh VM state on next launch.
Suggested Fixes
For the gvisor auto-recovery:
- Don't persist gvisor as the default — use it as a one-time fallback, not a permanent config change
- Add retry logic — if gvisor fails N times, revert to
auto - Allow explicit vmnet mode — the config validator only accepts
"auto"or"gvisor" - Surface the change to users — show a notification when the network mode is automatically changed
For VM corruption prevention:
- Validate rootfs on disk — store and check the uncompressed checksum, not just the compressed one
- Graceful VM shutdown — avoid force-killing the VM when vsock connect times out
- Auto-reset on repeated failures — after N consecutive boot failures with no console output, automatically delete and re-download the rootfs
- Limit force-kill retries — don't keep rebooting a VM that's clearly broken
Log Files
Relevant logs are in:
~/Library/Logs/Claude/cowork_vm_swift.log— Virtualization.framework events~/Library/Logs/Claude/cowork_vm_node.log— Node.js VM orchestration~/Library/Logs/Claude/coworkd.log— Guest daemon (no entries after corruption)~/Library/Logs/Claude/main.log— Electron app events
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗