WSL2: /mnt/c fails with "Input/output error (os error 5)" after the laptop sleeps
Symptom
The laptop was suspended with a WSL2 session open. After resume, every path under /mnt is dead:
$ ls /mnt/c
ls: reading directory '/mnt/c': Input/output error
$ cat /mnt/d/some/file
cat: /mnt/d/some/file: Input/output error
Python, Node and anything else that touches those paths reports the same thing as os error 5:
OSError: [Errno 5] Input/output error: '/mnt/c'
Native Linux filesystems are unaffected. /, /home, /mnt/wsl and /mnt/wslg behave normally, and
long-running processes that never touch /mnt keep going.
What it is not
Two wrong turns are easy here, so rule them out first.
It is not a permissions or mount-option problem. The mounts are still listed and still carry their original options:
$ grep drvfs /proc/mounts
C:\134 /mnt/c 9p rw,dirsync,noatime,aname=drvfs;path=C:\;uid=1000;gid=1000;symlinkroot=/mnt/ 0 0
A mount with broken permissions returns EACCES, not EIO. Rewriting /etc/wsl.conf automount options
changes nothing, because the mount table entry is intact — the transport behind it is not.
It is not fixed by remounting. sudo mount -o remount /mnt/c and umount + mount -t drvfs both fail
or reconnect to the same dead endpoint. The 9p transport to the Windows host is what died; the kernel mount
object survived the suspend, its peer did not.
The second symptom that identifies it
Check Windows interop, not just the filesystem:
$ cmd.exe /c "echo test"
-bash: /mnt/c/Windows/System32/cmd.exe: Input/output error
Interop binaries live under /mnt/c, so they die with the mounts. This is the tell: if both drive
access and cmd.exe / wsl.exe are broken while native paths work, you are looking at a dead host
transport, not a filesystem issue inside the distro.
It also explains why the obvious command does not work:
$ wsl.exe --shutdown
-bash: /mnt/c/Windows/System32/wsl.exe: Input/output error
You cannot restart WSL from inside WSL, because the tool you need is on the filesystem that is gone.
Fix
Run the shutdown from Windows, not from the distro. In PowerShell or cmd:
wsl --shutdown
Wait about 8 seconds — the VM needs to fully stop before it will start clean — then open your terminal again. The mounts come back with a fresh 9p transport.
Verify:
$ ls /mnt/c >/dev/null && echo "mounts ok"
mounts ok
$ cmd.exe /c "echo interop ok"
interop ok
Why this happens and what does not help
The Windows drives are exposed to the distro over a 9p transport (aname=drvfs) served by the Windows
side. A suspend/resume cycle can leave that channel unrecoverably broken while the guest keeps its mount
state, so every I/O against it returns EIO and the mount cannot heal itself. Restarting the utility VM
recreates the channel.
Things that cost me time and did not help:
- per-mount remount and
automounttweaks in/etc/wsl.conf— the mount entry was never the problem - killing and restarting the terminal or the shell — the transport is per-VM, not per-session
wsl --update— worth having current, but it does not repair a live broken channel
If you need to avoid the whole class of problem for long jobs, keep working data on the native Linux
filesystem (/home) instead of /mnt/c; those paths survive suspend/resume untouched.