Coding Agents & Terminal · recorded 2026-08-29 · applies to 1 tool(s) ✓ Verified

Problem: "No space left on device" in WSL while df shows hundreds of GB free (vhdx on a full host drive) —— Trove problem library

Verified 2026-08-29WSL reports No space left but df has space — the ext4.vhdx filled the Windows drive; locate it, free host space, and WSL resumes writing.

Quick fix

# One-liner: locate the vhdx + check host drive free space (PowerShell)
Get-ChildItem "$env:LOCALAPPDATAPackages*LocalStateext4.vhdx" | Select FullName, @{n='GB';e={[math]::Round($_.Length/1GB,1)}}
Get-PSDrive C | Select Used, Free

WSL resumes writing immediately once the host drive has free space.

What you will run into

In WSL, extracting/compiling/writing large files fails with No space left on device, yet df -h / clearly shows hundreds of GB free (/dev/sdd 1007G 190G 766G 20% /).

Your first reaction: "I clearly have space" — this is WSL2's most classic paradox: df shows the virtual capacity, not the real size of the vhdx file on the host disk.

Why this happens

WSL2's ext4 filesystem lives on a dynamically expanding vhdx virtual disk:

  • df shows the virtual capacity (up to ~1TB by default);
  • When a write needs the vhdx to physically expand, it requires free space on the host disk (C: by default);
  • Host disk full → expansion fails → the kernel returns ENOSPC ("No space left on device").

Hence the paradox of "df shows space, but can't write". Classic issues: microsoft/WSL#1665 (random ENOSPC), #4699 (372 comments: deleting files doesn't give space back to the host).

WSL2's ext4 filesystem lives inside a vhdx virtual disk: df reports the virtual disk's capacity ceiling (1TB-class by default), while real usage comes from the physical expansion of the vhdx file.

When a write needs expansion, the kernel asks the host disk (C: by default) for space — if the host disk is full, expansion fails and the kernel reports that write as ENOSPC.

That is the two-ledger paradox: "virtual capacity shows free space, the physical host has none".

Deterministic takeaway: if df -h / has space but writes fail, check the host disk (df -h /mnt/c) and the vhdx size (ls -lh *.vhdx);

deleted files not shrinking the vhdx is normal (sparse files only grow), compact it manually with wsl --shutdown then Optimize-VHD/diskpart compact;

the long-term fix is migrating the distro to a disk with room (wsl --export/--import) rather than squeezing a nearly-full disk.

Step by step

1. Find which drive the vhdx is on — Required

PowerShell:

Get-ChildItem "$env:LOCALAPPDATAPackages*LocalStateext4.vhdx" | Select FullName

Or the registry HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss\{GUID} BasePath.

2. Check the host drive's free space — Required

Get-PSDrive D

If the host drive Free is tiny (measured here: with D at 9GB free, a 2.7G write inside WSL hit ENOSPC) → free host-drive space (recycle bin / large files / other distros' vhdx) and it recovers immediately.

3. Make the vhdx give space back (root fix; deleting files doesn't shrink the disk) — Required

  • New WSL (2.4.4+): wsl --shutdown then wsl --manage <distro> --set-sparse true; deleted files return space automatically;
  • Older versions: wsl --shutdown + admin diskpart compact vdisk (or Hyper-V Optimize-VHD).

4. Move to a bigger drive — Required

wsl --export <distro> <file.tar>

At the new location wsl --import <distro> <dir> <file.tar> (after import, reset root/default distro settings; wsl --set-default).

5. Prevention — Required

docker-desktop and other distros each occupy their own vhdx; put large files on /mnt/c (direct host-drive passthrough, doesn't consume the vhdx).

How to confirm it works

dd if=/dev/zero of=/tmp/x.bin bs=1M count=5120 conv=fsync && rm /tmp/x.bin

No more No space left on device means success. Measured: before host cleanup, writing 5GB failed at ~2.7GB while df still showed 766G free; recovered after cleanup.

Other environments

EnvironmentNotes
Default install (C drive)vhdx in %LOCALAPPDATA%\Packages\*\LocalState\; free C space
Moved to D driveFree D space; measured trigger at 9GB free on this machine
Space not returned after deleting filesvhdx doesn't auto-shrink; use --set-sparse / diskpart compact
docker-desktopIts own vhdx takes space; handle the same way

Symptom

Extracting/compiling/writing large files inside WSL fails with No space left on device, while:

$ df -h /
/dev/sdd  1007G  190G  766G  20% /     # plenty free, right?
$ dd if=/dev/zero of=/tmp/x.bin bs=1M count=5120 conv=fsync
dd: IO error: No space left on device   # fails after ~2.7G

Key traits: df shows plenty of free space (even 80% idle); the failure point looks random (different files during extraction); users instinctively say "I do have enough space on my device" (verbatim in microsoft/WSL#1665).

Cause

WSL2's ext4 filesystem lives on a dynamically-expanding vhdx virtual disk: df reports the *virtual* capacity (up to ~1TB by default), not the actual size of the vhdx file on the host drive. When a write inside WSL requires the vhdx to physically grow, but the host drive (C: by default, or wherever the distro was imported) lacks free space, the expansion fails and the kernel returns ENOSPC. Hence the paradox: "df shows space, writes still fail". Related classics: microsoft/WSL#1665 (random ENOSPC), #4699 (372 comments: deleting files never returns space to the host).

Solution

  1. Locate the vhdx drive first: registry HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss\{GUID} BasePath,

or PowerShell Get-ChildItem "$env:LOCALAPPDATA\Packages\*\LocalState\ext4.vhdx";

  1. Check the host drive's free space: Get-PSDrive for the drive holding the vhdx — in this repro, D: had only 9GB free

and a 2.7GB write inside WSL already hit ENOSPC. Freeing host space (recycle bin, large files, other distro vhdx files) restores it immediately;

  1. Return space to the host (root fix; deleted files do not shrink the disk):
  • Newer WSL (2.4.4+): wsl --shutdown then wsl --manage <distro> --set-sparse true — sparse vhdx, space returns automatically on delete;
  • Older versions: wsl --shutdown + admin diskpart compact vdisk (or Hyper-V Optimize-VHD);
  1. Move to a bigger drive: wsl --export <distro> <file.tar> → wsl --import <distro> <dir> <file.tar> at the new location

(note: after import, re-set the default distro/user as needed);

  1. Prevention: docker-desktop and other distros each own a vhdx; keep large files in /mnt/c (host passthrough, no vhdx growth),

or cap the vhdx size where supported.

Verification Evidence
  • Local repro (2026-08-29, WSL Ubuntu, vhdx at D:\WSL\Ubuntu, host D: had only 9GB free):
  • Baseline: df shows 766G free / vhdx file 194.90GB / D: Free 9.0GB;
  • Repro: dd writing 5GB failed at ~2.7GB with IO error: No space left on device, then df -h / still showed 766G free;
  • Mechanism check: D: Free 9GB (no physical room for the vhdx to grow) vs df virtual capacity — same symptom class as #1665;
  • Cleanup: after deleting the partial file, df recovered but D: Free and vhdx size stayed unchanged (deletion does not return space — the #4699 pain point);
  • Not tested (needs admin/restart, honestly marked): diskpart compact, --set-sparse, --export/--import migration.

Evidence details kept locally (2026-08-29)

Related canonicals

Read in order: precondition -> same root / same domain / related:

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

wsl

Bundled solutions (combos)

This problem is part of the following verified bundles.

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

Source: https://github.com/microsoft/WSL/issues/1665

← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk