lima-vm/lima · error

failed to stat raw tmp file %q: %w

Error message

failed to stat raw tmp file %q: %w

What it means

Immediately after opening the converted raw temp file, ensureRawInCache calls Stat() to obtain its size for MakeSparse. A Stat failure (wrapped and with the file descriptor closed) aborts finalization of the sparse raw image.

Source

Thrown at pkg/downloader/downloader.go:487

	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)
	}

	algo := digest.Canonical
	if originalDigest != "" {
		algo = originalDigest.Algorithm()

View on GitHub (pinned to dd909d0973)

Solutions

  1. Rerun the download; the error is usually transient (concurrent deletion).
  2. Ensure no cleanup job removes files under the cache directory while downloads are running.
  3. Check the health of the filesystem hosting CacheDir (dmesg, smartctl).

Example fix

// before: cron job wiping cache mid-download
# cron: 0 * * * * rm -rf ~/.cache/lima/images/*
// after: prune only stale entries, not during active use
# use limactl's cache prune or guard with a lock
Defensive patterns

Strategy: retry

Validate before calling

// ensure no concurrent cache pruners are running before a long download
if isCachePrunerRunning() { return errors.New("suspend cache cleanup during downloads") }

Try / catch

res, err := d.Download(ctx, local, url)
if err != nil && strings.Contains(err.Error(), "failed to stat raw tmp file") {
    time.Sleep(time.Second)
    res, err = d.Download(ctx, local, url) // retry: usually a transient concurrent deletion
}

Prevention

When it happens

Trigger: rawTmpF.Stat() returns an error in ensureRawInCache — rare; usually caused by the file being deleted/unlinked concurrently while open, or filesystem-level I/O errors on the cache volume.

Common situations: Concurrent cache pruning (another limactl or cleanup script removing raw.tmp) during a download; failing/flaky disk or network mount hosting the cache.

Related errors


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/1ee191e29103c81d. Report an issue: GitHub.