{"record":{"id":"e23c966f91495d55","repo":"lima-vm/lima","slug":"failed-to-remove-stale-raw-image-q-w","errorCode":null,"errorMessage":"failed to remove stale raw image %q: %w","messagePattern":"failed to remove stale raw image %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/downloader/downloader.go","lineNumber":497,"sourceCode":"\t// Ensure the image is sparse to save cache space.\n\trawTmpF, err := os.OpenFile(rawPathTmp, os.O_RDWR, 0o644)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to open raw tmp file %q: %w\", rawPathTmp, err)\n\t}\n\tfi, err := rawTmpF.Stat()\n\tif err != nil {\n\t\t_ = rawTmpF.Close()\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to stat raw tmp file %q: %w\", rawPathTmp, err)\n\t}\n\tif err := diskUtil.MakeSparse(ctx, rawTmpF, fi.Size()); err != nil {\n\t\tlogrus.WithError(err).Warnf(\"Failed to make %q sparse (non-fatal)\", rawPathTmp)\n\t}\n\tif err := rawTmpF.Close(); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to close raw tmp file %q: %w\", rawPathTmp, err)\n\t}\n\n\tif err := os.Remove(rawImgConvPath); err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to remove stale raw image %q: %w\", rawImgConvPath, err)\n\t}\n\tif err := os.Rename(rawPathTmp, rawImgConvPath); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to replace original with raw image: %w\", err)\n\t}\n\n\talgo := digest.Canonical\n\tif originalDigest != \"\" {\n\t\talgo = originalDigest.Algorithm()\n\t}\n\trawDigest, err := calculateFileDigest(rawImgConvPath, algo)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to calculate digest of raw image: %w\", err)\n\t}\n\n\trawDigestPath := filepath.Join(imgConvPath, \"raw.digest\")\n\trawDigestPathTmp := rawDigestPath + \".tmp\"\n\tdefer os.Remove(rawDigestPathTmp)\n\tif err := os.WriteFile(rawDigestPathTmp, []byte(rawDigest.String()), 0o644); err != nil {","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/downloader/downloader.go#L479-L515","documentation":"Before promoting the freshly converted raw image into place, ensureRawInCache removes any stale existing imgconv/raw file. If os.Remove fails for a reason other than the file not existing, the conversion is aborted with this wrapped error. This is a pre-rename cleanup step guarding the atomic replacement of the cached raw image.","triggerScenarios":"An old imgconv/raw exists in the cache and os.Remove returns e.g. EACCES/EPERM (read-only dir or file), EBUSY (file held by a running VM/qemu), or EISDIR/immutable attribute — anything besides ErrNotExist.","commonSituations":"Cache directory or files made read-only by permissions or ownership (e.g. created by root, now run as user); a previous VM process still holds the raw image open; immutable flag set after a crash-recovery tool ran.","solutions":["Fix ownership/permissions on the cache imgconv directory: chown/chmod so the current user can delete files","Ensure no running VM or qemu-img process still uses the cached raw image; stop instances before re-downloading","Manually remove the stale file/directory (<cacheDir>/download/by-url-sha256/<hash>/imgconv) and retry","Check for immutable flags (chattr -i) or read-only mounts on the cache volume"],"exampleFix":"// before: permission denied removing stale raw image\n$ ls -l ~/.lima/_cache/download/by-url-sha256/<hash>/imgconv/raw  # owned by root\n// after\n$ sudo chown -R $(whoami) ~/.lima/_cache  # or delete: rm -rf .../imgconv","handlingStrategy":"validation","validationCode":"rawImgConvPath := filepath.Join(cacheDir, \"download\", \"by-url-sha256\", key, \"imgconv\", \"raw\")\nif _, err := os.Stat(rawImgConvPath); err == nil {\n    if err := os.Remove(rawImgConvPath); err != nil {\n        return fmt.Errorf(\"cannot clear stale raw image (check perms/locks): %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to remove stale raw image\") {\n    // stop VMs, fix ownership, retry\n}","preventionTips":["Run all limactl operations as the same (non-root) user so cache files share one owner","Stop running VMs before re-downloading the same image","Avoid placing the cache on NFS or removable media","Pre-clear the cache entry when you know an image URL changed content"],"tags":["go","filesystem","cache","permissions"],"backgroundTag":"permission-denied","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}