{"record":{"id":"f9f6fe873dc30d88","repo":"lima-vm/lima","slug":"failed-to-remove-stale-raw-digest-file-q-w","errorCode":null,"errorMessage":"failed to remove stale raw digest file %q: %w","messagePattern":"failed to remove stale raw digest file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/downloader/downloader.go","lineNumber":519,"sourceCode":"\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 {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to write raw digest file: %w\", err)\n\t}\n\tif err := os.Remove(rawDigestPath); err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to remove stale raw digest file %q: %w\", rawDigestPath, err)\n\t}\n\tif err := os.Rename(rawDigestPathTmp, rawDigestPath); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to rename raw digest file: %w\", err)\n\t}\n\n\treturn rawImgConvPath, rawDigest, nil\n}\n\nfunc calculateFileDigest(path string, algo digest.Algorithm) (digest.Digest, error) {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer f.Close()\n\n\treturn algo.FromReader(f)\n}\n","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/downloader/downloader.go#L501-L537","documentation":"Before renaming raw.digest.tmp into place, any pre-existing raw.digest is removed. If os.Remove fails for a reason other than ErrNotExist, the cache update aborts with this error. It prevents a stale digest file from shadowing the new one when rename would otherwise fail or leave inconsistent state.","triggerScenarios":"An old imgconv/raw.digest exists and os.Remove returns EACCES/EPERM (read-only or root-owned file), EBUSY (file held open), or an immutable attribute — any non-ErrNotExist failure.","commonSituations":"Cache files previously written by a privileged run are now undeletable by the normal user; backup or sync software locks digest files on Windows/NFS; manual tampering left odd permissions.","solutions":["chown/chmod the imgconv directory contents so the current user can delete the digest file","Stop any process holding the digest file open (VMs, sync tools) and retry","Remove the whole cache entry directory manually and re-download","Check and clear immutable flags (chattr -i) on the file"],"exampleFix":"// before\n$ rm ~/.lima/_cache/download/by-url-sha256/<hash>/imgconv/raw.digest  # EACCES\n// after\n$ sudo chown -R $(whoami) ~/.lima/_cache && limactl start <instance>","handlingStrategy":"validation","validationCode":"digestPath := filepath.Join(cacheDir, \"download\", \"by-url-sha256\", key, \"imgconv\", \"raw.digest\")\nif _, err := os.Stat(digestPath); err == nil {\n    if err := os.Remove(digestPath); err != nil {\n        return fmt.Errorf(\"stale digest not removable, fix permissions/locks first: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to remove stale raw digest file\") {\n    // chown -R the cache and stop locking processes before retrying\n}","preventionTips":["Avoid mixing sudo limactl with normal-user runs against one LIMA_HOME","Exclude the cache from backup/sync tools that lock files","Never set immutable flags on cache contents","Use a consistent user for all Lima operations"],"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"}