lima-vm/lima · error
failed to open raw tmp file %q: %w
Error message
failed to open raw tmp file %q: %w
What it means
After successfully converting the image to rawPathTmp, ensureRawInCache reopens the temp file with os.OpenFile(O_RDWR) to sparsify it. If opening fails, this error wraps the OS error. Failure here means the conversion result exists but cannot be finalized.
Source
Thrown at pkg/downloader/downloader.go:482
func ensureRawInCache(ctx context.Context, imagePath, format string, originalDigest digest.Digest) (string, digest.Digest, error) {
imgConvPath := filepath.Join(filepath.Dir(imagePath), "imgconv")
if err := os.MkdirAll(imgConvPath, 0o700); err != nil {
return "", "", err
}
rawImgConvPath := filepath.Join(imgConvPath, "raw")
logrus.Infof("Converting %s image to raw sparse format in cache: %q", format, rawImgConvPath)
rawPathTmp := filepath.Join(imgConvPath, "raw.tmp")
defer os.Remove(rawPathTmp)
diskUtil := proxyimgutil.NewDiskUtil(ctx)
if err := diskUtil.Convert(ctx, raw.Type, imagePath, rawPathTmp, nil, false); err != nil {
return "", "", fmt.Errorf("failed to convert %q to raw: %w", imagePath, err)
}
// Ensure the image is sparse to save cache space.
rawTmpF, err := os.OpenFile(rawPathTmp, os.O_RDWR, 0o644)
if err != nil {
return "", "", fmt.Errorf("failed to open raw tmp file %q: %w", rawPathTmp, err)
}
fi, err := rawTmpF.Stat()
if err != nil {
_ = rawTmpF.Close()
return "", "", fmt.Errorf("failed to stat raw tmp file %q: %w", rawPathTmp, err)
}
if err := diskUtil.MakeSparse(ctx, rawTmpF, fi.Size()); err != nil {
logrus.WithError(err).Warnf("Failed to make %q sparse (non-fatal)", rawPathTmp)
}
if err := rawTmpF.Close(); err != nil {
return "", "", fmt.Errorf("failed to close raw tmp file %q: %w", rawPathTmp, err)
}
if err := os.Remove(rawImgConvPath); err != nil && !errors.Is(err, os.ErrNotExist) {
return "", "", fmt.Errorf("failed to remove stale raw image %q: %w", rawImgConvPath, err)
}
if err := os.Rename(rawPathTmp, rawImgConvPath); err != nil {
return "", "", fmt.Errorf("failed to replace original with raw image: %w", err)View on GitHub (pinned to dd909d0973)
Solutions
- Check ownership/permissions of the cache directory and the imgConv subdir; fix with chown/chmod.
- Ensure only one download for the same image runs at a time, or clean the cache of stale raw.tmp files.
- Move the cache to a writable local filesystem (adjust CacheDir).
Example fix
// before: root-owned cache $ sudo chown -R $(id -u):$(id -g) ~/.cache/lima $ rm -f ~/.cache/lima/images/*/raw.tmp // after: reopen succeeds, sparsification proceeds
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(cacheDir)
if err != nil || !info.IsDir() {
return fmt.Errorf("cache dir not writable: %w", err)
}
if err := unix.Access(cacheDir, unix.W_OK); err != nil {
return fmt.Errorf("cache dir lacks write permission: %w", err)
} Try / catch
res, err := d.Download(ctx, local, url)
if err != nil && strings.Contains(err.Error(), "failed to open raw tmp file") {
// fix cache ownership/permissions, remove stale raw.tmp, retry
} Prevention
- Keep a single OS user for all Lima operations so cache ownership is uniform.
- Avoid concurrent limactl processes operating on the same cache entry.
- Do not place CacheDir on read-only or root-owned volumes.
When it happens
Trigger: os.OpenFile(rawPathTmp, os.O_RDWR, 0o644) fails right after conversion — typically permission problems on the cache dir, the file being locked/removed by a concurrent process, or a read-only mount.
Common situations: Cache shared between users/VMs with mixed ownership; concurrent limactl downloads racing on the same cache entry; containers running as non-root against a root-owned cache.
Related errors
- failed to read raw digest file %q: %w
- failed to stat raw tmp file %q: %w
- caching-only mode requires the cache directory to be specifi
- invalid digest in raw digest file %q: %w
- failed to convert image to raw: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/58b2831ccc16180b.
Report an issue: GitHub.