containerd/containerd · error
failed to create base vhd: %w
Error message
failed to create base vhd: %w
What it means
The base scratch VHD could not be created by createScratchVHD (with NTFS formatting) when it did not already exist. createDifferencingScratchVHDs wraps the underlying failure — which itself may be an option-application error, stat failure, or a vhd.CreateVirtualDisk/format failure — and cleanup removes partial files afterward.
Source
Thrown at plugins/snapshots/windows/cimfs.go:424
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to stat diff VHD: %w", err)
} else if baseVHDExists && err == nil {
diffVHDExists = true
} else {
// remove this diff VHD, it must be recreated with the new base VHD.
os.RemoveAll(diffVHDPath)
}
defer func() {
if err != nil {
os.RemoveAll(baseVHDPath)
os.RemoveAll(diffVHDPath)
}
}()
if !baseVHDExists {
if err = createScratchVHD(ctx, baseVHDPath, WithNTFSFormat()); err != nil {
return fmt.Errorf("failed to create base vhd: %w", err)
}
}
if !diffVHDExists {
// Create the differencing disk that will be what's copied for the final rw layer
// for a container.
if err = vhd.CreateDiffVhd(diffVHDPath, baseVHDPath, vhdBlockSizeInBytes); err != nil {
return fmt.Errorf("failed to create differencing disk: %w", err)
}
}
// Grant VM group access to the differencing VHD (base VHD access is already granted by createSingleVHD)
if err = security.GrantVmGroupAccess(diffVHDPath); err != nil {
return fmt.Errorf("failed to grant vm group access to %s: %w", diffVHDPath, err)
}
return nil
}
View on GitHub (pinned to 4246446a2b)
Solutions
- Unwrap to the root cause from createScratchVHD and fix it (space, permissions, VDS availability).
- Free disk space on the volume hosting the snapshotter root.
- Ensure containerd runs elevated enough to create virtual disks (Virtual Disk APIs).
- Check that security software isn't blocking vhd image creation; delete any corrupt leftover base VHD and restart containerd.
Example fix
// before: full disk // after: free space then re-init // Get-Volume C # verify free space // Restart-Service containerd
Defensive patterns
Strategy: validation
Validate before calling
func precheckBaseVHDCreation(baseVHDPath string, needBytes uint64) error {
if fi, err := os.Stat(filepath.Dir(baseVHDPath)); err != nil || !fi.IsDir() {
return fmt.Errorf("scratch dir missing or invalid")
}
if free, err := freeDiskSpace(filepath.VolumeName(baseVHDPath)); err != nil || free < needBytes {
return fmt.Errorf("insufficient space for base VHD")
}
return nil
} Try / catch
if err := createScratchVHD(ctx, baseVHDPath, WithNTFSFormat()); err != nil {
if errors.Is(err, os.ErrExist) { os.Remove(baseVHDPath); retry() }
else if isDiskFull(err) { freeSpace(); retry() }
else { return fmt.Errorf("cannot create base vhd, check VDS/privileges: %w", err) }
} Prevention
- Ensure adequate free space before starting containerd.
- Run containerd with privileges sufficient for Virtual Disk API calls.
- Verify policy/security software permits vhdx creation.
- Let the built-in cleanup (RemoveAll on error) finish before re-running init.
When it happens
Trigger: First snapshotter init (baseVHDExists==false) calls createScratchVHD(ctx, baseVHDPath, WithNTFSFormat()); the underlying vhd.CreateVirtualDisk, VHD mount/format step, or an option callback fails (no disk space, Virtual Disk Service unavailable, insufficient privileges).
Common situations: Disk full on the containerd volume; Windows Virtual Disk Service (vds) or vhdx APIs blocked by policy/security software; running containerd without required privileges; file already exists as a corrupt leftover handled by the wrong branch.
Related errors
- failed to create differencing disk: %w
- failed to create scratch layer: %w
- failed to expand sandbox vhdx size to %d bytes: %w
- failed to stat base VHD: %w
- failed to stat diff VHD: %w
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/cbbb1d75ced16ee5.
Report an issue: GitHub.