Corrective Action: WSL VM Termination During Claude Code Sessions
Date: 2026-04-23 Category: Missing Configuration Impact: Chris Carolan's primary interface to the AI Leadership Team. Two WSL VM terminations within 30 minutes on 2026-04-22 ended active Claude Code sessions mid-conversation, destroying in-flight context. At least one prior occurrence at an undocumented earlier date. Resolution Time: ~90 minutes from first observed symptom to empirical verification window open; 15h44m continuous-session baseline achieved by verification close.
Incident
What Happened
On the morning of 2026-04-22, Chris Carolan's WSL VM on workstation VFT-CommandCtr terminated unexpectedly multiple times without warning, ending his Claude Code sessions in the middle of active work. One session terminated after only 96 seconds of life. Chris runs 5+ Claude Code sessions daily as the primary interface to the AI Leadership Team; each termination destroyed the session's in-flight context and halted work across multiple agent domains simultaneously.
Timeline
All times CDT.
| Time | Event |
|---|---|
| 2026-04-22 11:14:30 | WSL VM port deleted — session 1 terminated (Hyper-V-VmSwitch-Operational event log) |
| 2026-04-22 11:28:34 | WSL VM port created — session 2 started |
| 2026-04-22 11:30:07 | WSL VM port deleted — session 2 terminated after 96 seconds |
| 2026-04-22 11:43:09 | WSL VM port created — session 3 (diagnostic session) |
| 2026-04-22 ~11:50 | Corrective action applied (.wslconfig hardened with three additional settings) |
| 2026-04-22 12:05 | Chris ran wsl --shutdown from PowerShell and relaunched cold to pick up the new configuration |
| 2026-04-22 12:05 | Post-restart structural verification complete (zero WSLg processes, clean dmesg, working DNS) |
| 2026-04-22 ~21:47 | Current WSL VM launched (the one Chris is running at report time) |
| 2026-04-23 03:49 | Empirical verification: zero unexpected drops since 12:05. Chris confirmed a 15h44m continuous-session baseline across his normal work rhythm. |
Root Cause
The VFT-CommandCtr workstation runs two GPU-intensive subsystems on shared hardware: the WSLg GUI subsystem inside WSL2, and the NVENC media relay on the Windows host. WSLg consumes GPU resources through the Direct3D ioctl interface whether or not Chris runs any Linux GUI applications. On this workstation Chris runs none — voice, media relay, browser, and production tools all live on the Windows side — so WSLg's GPU consumption produced no benefit but imposed real cost.
That cost manifested as a Direct3D ioctl failure storm at every WSL boot (misc dxg: dxgk: dxgkio_query_adapter_info: Ioctl failed: -22, approximately 12 instances per boot), visible in dmesg and correlated with the corrupted journald state observed at every boot (File /var/log/journal/.../system.journal corrupted or uncleanly shut down, renaming and replacing). When GPU driver state became unstable under simultaneous pressure from the NVENC relay and WSLg, Hyper-V terminated the WSL VM externally to protect the Windows host. The absence of kernel crash dumps (despite WSL_ENABLE_CRASH_DUMP=1 being set) and the presence of port-delete events in the Windows Event Log together prove the termination originated on the Windows host side, not from a kernel panic inside WSL.
Two contributing factors compounded the primary mechanism:
- Windows Insider Preview build 10.0.26200.8246 (Canary/Dev channel) — bleeding-edge, with known WSL2 stability issues and aggressive Hyper-V idle-timeout behavior. The default
vmIdleTimeouton this build can terminate an idle VM with no visible warning to the guest. - DNS tunneling (default
trueon recent WSL versions) was throwinggetaddrinfo()errors at boot (WSL (303) ERROR: CheckConnection: getaddrinfo() failed: -5), adding startup noise and minor additional instability.
Memory pressure was ruled out: the VM had 45Gi free of 47Gi at boot. This was not OOM. The 96-second session-2 lifetime is particularly diagnostic — the VM was terminated externally before it could accumulate any meaningful memory pressure or runtime load.
Category: Missing Configuration
The .wslconfig file at C:\Users\Coach Chris\.wslconfig existed and had reasonable resource limits (memory=48GB, swap=8GB, processors=20), but was missing three hardening settings that would have prevented the incident:
guiApplications=false— disables WSLg, eliminates GPU contention with the NVENC relayvmIdleTimeout=-1— prevents Hyper-V auto-shutdown of an idle VMdnsTunneling=false— reverts to legacy/etc/resolv.confDNS, eliminates boot-timegetaddrinfoerrors
This is the "default configuration is not hardened" pattern. The default WSL2 configuration assumes a standard developer workstation with no GPU-heavy host-side workloads. VFT-CommandCtr violates that assumption because it runs the NVENC media relay on the host, making the default WSLg behavior actively harmful rather than merely unused. A configuration tuned for the general case fails when the workstation's workload profile deviates from the general case.
Fix Applied
Immediate Resolution
Mender appended three hardening settings to C:\Users\Coach Chris\.wslconfig under the existing [wsl2] section. Existing settings (memory, swap, processors) were left untouched. Each appended setting carries an inline comment explaining its purpose for future reference. Chris then ran wsl --shutdown from PowerShell and relaunched Claude Code cold so the VM would pick up the new configuration on next start.
Code/Configuration Changes
| File | Change |
|---|---|
C:\Users\Coach Chris\.wslconfig |
Appended vmIdleTimeout=-1 under [wsl2] — prevents Hyper-V idle auto-shutdown. |
C:\Users\Coach Chris\.wslconfig |
Appended dnsTunneling=false under [wsl2] — reverts to /etc/resolv.conf DNS; eliminates the getaddrinfo() failed: -5 boot error. |
C:\Users\Coach Chris\.wslconfig |
Appended guiApplications=false under [wsl2] — disables WSLg subsystem; eliminates Direct3D ioctl failure storm and GPU contention with the NVENC media relay. |
Verification
Structural verification (2026-04-22 12:05 CDT, immediately post-restart):
- Zero
weston,Xwayland, or WSLg-related processes running.ps auxreturned empty for the GUI subsystem. dmesgshows only the benignhv_vmbus: registering driver dxgkrnlkernel driver init line. The 12-instance Direct3D ioctl failure storm seen at every prior boot is gone./etc/resolv.confis the legacy auto-generated format pointing at the Hyper-V virtual switch (172.20.240.1), not the tunneling stub resolver.- DNS resolution functional:
getent hosts google.comreturned three IPv6 answers.
Empirical verification (2026-04-23 03:49 CDT, 15h44m post-fix):
- Current WSL VM uptime: 6h02m continuous (launched 2026-04-22 ~21:47 CDT).
- Chris confirmed zero unexpected drops across his normal work rhythm between fix application and verification window close.
dmesgon the current boot remains clean — no Direct3D ioctl errors, no weston warnings.- WSLg process count remains zero.
Prevention Measures
Rules to Add
| Layer | File | Rule |
|---|---|---|
| Critical Lessons | memory/MEMORY.md (# Build Notes section) |
NEVER leave WSLg (guiApplications) enabled on the VFT-CommandCtr workstation. It contends with the NVENC media relay for GPU resources and causes Hyper-V to terminate the WSL VM, ending active Claude Code sessions. Fixed 2026-04-22 after two VM terminations in 30 minutes killed in-flight work. Required .wslconfig settings on this workstation: guiApplications=false, vmIdleTimeout=-1, dnsTunneling=false. |
| Reference | memory/reference_chris_workstation.md |
Document the .wslconfig hardening as part of the workstation profile. Any rebuild or migration of VFT-CommandCtr must re-apply guiApplications=false, vmIdleTimeout=-1, dnsTunneling=false — the default WSL2 configuration is unsafe on this workstation because the NVENC media relay contends with WSLg for GPU resources. |
| Operations | memory/operations.md |
Add "WSL stability" check to end-of-day routine: verify current VM uptime exceeds the shift length, and confirm no unexpected terminations in the Windows Event Log (Hyper-V-VmSwitch-Operational, port 67/69 events). |
Detection Triggers
- If a future Windows Update migrates VFT-CommandCtr to a new Insider build, rerun the diagnostic: check
dmesgfor Direct3D ioctl failures, check Windows Event Log for Hyper-V-VmSwitch port 67/69 event frequency, and confirm the three hardening settings survived. Configuration file survival is not guaranteed across major Insider builds. - If Chris reports any unexplained session termination, first check current WSL uptime against expected shift length (and check Windows Event Log for VM port-delete events) before assuming a Claude Code or terminal issue. "My session died" is a WSL symptom until proven otherwise.
- If the NVENC media relay behavior changes (new relay path, different GPU encoder, additional host-side GPU consumers), re-audit GPU contention with WSL. The fix assumes a specific host-side GPU workload profile.
Lessons
The default configuration of a general-purpose tool is tuned for the common case. When a workstation's workload profile deviates from the common case — in this incident, a GPU-heavy host-side application running alongside WSL — the default becomes actively harmful rather than merely sub-optimal. Hardening configurations must be authored for the specific workstation profile, not inherited from the default. This generalizes beyond WSL: any subsystem that makes assumptions about resource contention will fail silently when those assumptions are violated, and the failure mode will look like an unrelated problem ("my session died") rather than a configuration defect. The fix is to document the workstation's actual workload profile and harden every default that conflicts with it.
Related Incidents
This is the third Missing Configuration incident on VFT-CommandCtr in six weeks. Echo's pattern search surfaced two prior incidents that share the same failure shape as this one:
| Date | Incident | Root cause mechanism | CAR |
|---|---|---|---|
| 2026-03-08 | CRLF Token Infrastructure | Default Windows line-ending behavior produced CRLF-terminated .env files; bash source failed silently on every session. 29 files converted to LF + .editorconfig committed. |
docs/quality/cars/2026-03-08-corrective-crlf-token-infrastructure.md |
| 2026-03-15 | Supabase Connectivity WSL2 | WSL2 cannot route IPv6; Supabase DB hosts are IPv6-only. Default connection path was not viable on this workstation. Fix: REST-over-HTTP configuration + MEMORY.md Critical Lesson + vf-tech-stack.md Supabase section + vf-self-correction.md Infrastructure Trigger. |
docs/quality/cars/2026-03-15-corrective-supabase-connectivity.md |
| 2026-04-22 | WSL VM Termination (this incident) | WSLg (default guiApplications=true) contends with NVENC media relay for GPU on the Windows host; Hyper-V terminates the WSL VM. Fix: .wslconfig hardened with three settings. |
This report. |
Pattern observations
All three incidents are the same class: default tool configuration is not hardened for VFT-CommandCtr's specific topology (Windows + WSL2 bridge, IPv6 routing, GPU shared with NVENC media relay). Each tool (git, PostgreSQL driver, Hyper-V/WSLg) ships with defaults optimized for a generic user. Chris's workstation profile breaks those defaults in ways that are invisible until they cause a failure — and the failure mode always looks like something else ("can't source env", "database unreachable", "session died").
None of the prior fixes captured a generalized lesson. Each was treated as a one-off. This third recurrence demonstrates that the pattern itself needs to be documented, not just the specific instances.
Prior WSL VM termination incidents
No documented prior incident of WSL VM termination or session-kill by Hyper-V exists in memory files, 34 CARs, incident-log.json, or 12 months of git history. Chris's recollection that "this has happened once before" is not captured in the documented trail — the prior instance predates systematic CAR discipline.