lima-vm/lima · error

failed to close raw tmp file %q: %w

Error message

failed to close raw tmp file %q: %w

What it means

ensureRawInCache converts a downloaded VM disk image to a sparse raw copy under <cache>/imgconv/raw. After making the tmp file sparse, it closes the file descriptor; if Close() reports an error (often a deferred flush/writeback failure or EIO), the operation is aborted with this message wrapping the OS error. Close errors on freshly-written files usually indicate disk problems, since buffered data may be flushed at close time.

Source

Thrown at pkg/downloader/downloader.go:493

	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()
	}
	rawDigest, err := calculateFileDigest(rawImgConvPath, algo)
	if err != nil {
		return "", "", fmt.Errorf("failed to calculate digest of raw image: %w", err)
	}

View on GitHub (pinned to dd909d0973)

Solutions

  1. Check host disk space with df on the LIMA_HOME/cache volume and free space, then retry the download
  2. Verify the cache directory is on reliable local storage, not a flaky network mount; move cacheDir to a local disk
  3. Delete the instance/cache entry (imgconv dir) to force a clean re-conversion
  4. Check dmesg/filesystem health (fsck) for underlying I/O errors if the problem repeats
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: ensure cache volume has free space and is writable
fi, err := os.Stat(cacheDir)
if err != nil || !fi.IsDir() { return fmt.Errorf("cache dir unusable: %w", err) }
if err := unix.Access(cacheDir, unix.W_OK); err != nil { return fmt.Errorf("cache dir not writable: %w", err) }

Try / catch

res, err := downloader.Download(url, opts...)
if err != nil {
    if strings.Contains(err.Error(), "failed to close raw tmp file") {
        // check disk space / fs health, clear imgconv dir, retry once
        os.RemoveAll(filepath.Join(cacheDir, "download"))
    }
    return err
}

Prevention

When it happens

Trigger: Downloading a non-ISO disk image whose format is not in the WithImageFormats() list, so ensureRawInCache runs and closes imgconv/raw.tmp; Close() returns a non-nil error (e.g. ENOSPC flushed at close, EIO, or file already closed by an underlying bug).

Common situations: Host disk nearly full so sparse-writeback fails at close; NFS/network filesystems where close can report I/O errors; corrupted cache directory on removable media that was unplugged mid-download.

Related errors


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