containerd/containerd · error
failed to create '%s' temp file: %w
Error message
failed to create '%s' temp file: %w
What it means
Thrown by openOrCreateScratch when runhcs.CreateScratchWithOpts fails to create the temporary scratch VHD file. The temp file is removed and the underlying runhcs error (typically a runhcs invocation failure) is wrapped. This means the Hyper-V/container host tooling could not produce a blank scratch.vhdx of the requested size.
Source
Thrown at plugins/snapshots/lcow/lcow.go:470
scratchTempName := fmt.Sprintf("scratch-%s-tmp.vhdx", strconv.Itoa(int(1e9 + r%1e9))[1:])
scratchTempPath := filepath.Join(s.root, scratchTempName)
// Create the scratch
rhcs := runhcs.Runhcs{
Debug: true,
Log: filepath.Join(s.root, "runhcs-scratch.log"),
LogFormat: runhcs.JSON,
Owner: "containerd",
}
opt := runhcs.CreateScratchOpts{
SizeGB: sizeGB,
}
if err := rhcs.CreateScratchWithOpts(ctx, scratchTempPath, &opt); err != nil {
os.Remove(scratchTempPath)
return nil, fmt.Errorf("failed to create '%s' temp file: %w", scratchTempName, err)
}
if err := os.Rename(scratchTempPath, scratchFinalPath); err != nil {
os.Remove(scratchTempPath)
return nil, fmt.Errorf("failed to rename '%s' temp file to 'scratch.vhdx': %w", scratchTempName, err)
}
scratchSource, err = os.OpenFile(scratchFinalPath, os.O_RDONLY, 0700)
if err != nil {
os.Remove(scratchFinalPath)
return nil, fmt.Errorf("failed to open scratch.vhdx for read after creation: %w", err)
}
} else {
log.G(ctx).Debugf("scratch vhd %s was already present. Retrieved from cache", vhdFileName)
}
return scratchSource, nil
}
func (s *snapshotter) parentIDsToParentPaths(parentIDs []string) []string {
var parentLayerPaths []stringView on GitHub (pinned to 4246446a2b)
Solutions
- Verify runhcs.exe is present and functional on PATH (run `runhcs --version`) and matches your containerd version
- Enable required Windows features: Hyper-V and Containers (Install-WindowsFeature Hyper-V, Containers)
- Free disk space on the volume hosting the snapshot root or reduce the requested sizeGB
- Check the wrapped runhcs error output in logs for the concrete Win32/HCS failure code
Example fix
// before: LCOW snapshotter on host without Hyper-V Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart // after: scratch creation succeeds via runhcs
Defensive patterns
Strategy: retry
Validate before calling
const hyperVReady = await run('powershell -c "(Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V).State"')
if (!hyperVReady.includes('Enabled')) throw new Error('Enable Hyper-V before LCOW snapshots')
const freeGB = await getFreeDiskGB(snapshotRoot)
if (freeGB < requestedSizeGB * 1.1) throw new Error('insufficient disk space for scratch creation') Type guard
function isRunhcsError(e: unknown): e is Error & { stderr?: string } {
return e instanceof Error && 'stderr' in e
} Try / catch
try {
await createSnapshotWithScratch(sizeGB)
} catch (err) {
if (isTransient(err)) return retryWithBackoff(err)
log.error('scratch creation failed; verify runhcs and Hyper-V', err)
throw err
} Prevention
- Verify runhcs.exe availability and version parity with containerd at install time
- Enable Hyper-V/Containers features before deploying LCOW workloads
- Alert on snapshot-volume free space below the largest configured scratch size
- Capture runhcs stderr in logs for concrete failure codes
When it happens
Trigger: rhcs.CreateScratchWithOpts(ctx, scratchTempPath, &opt) returns an error while creating a new scratch VHD (missing or broken runhcs.exe, Hyper-V not enabled, invalid sizeGB, insufficient disk space).
Common situations: Running LCOW containers on a Windows host without the Hyper-V feature/Host Compute Service installed; runhcs version mismatch with containerd; disk-full on the snapshot volume; requesting a scratch size larger than the available disk.
Related errors
- failed to convert tar2ext4 vhd: %w
- failed to open vhd %s for read: %w
- failed to open scratch.vhdx for read after creation: %w
- failed to apply config opt: %w
- failed to sync tar2ext4 vhd to disk: %w
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/4bee3b03c4dc8d53.
Report an issue: GitHub.