{"record":{"id":"493b50a67eababe2","repo":"jdx/mise","slug":"local-cas-blob-failed-digest-verification","errorCode":null,"errorMessage":"local CAS blob failed digest verification: {}","messagePattern":"local CAS blob failed digest verification: (.+?)","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"crates/mise-cache-core/src/local.rs","lineNumber":49,"sourceCode":"    /// Resolve the storage path for a validated digest.\n    pub fn path_for(&self, digest: &CacheDigest) -> Result<PathBuf> {\n        digest.validate()?;\n        Ok(self\n            .root\n            .join(\"cas/v1\")\n            .join(&digest.algorithm)\n            .join(&digest.hash[..2])\n            .join(format!(\"{}-{}\", digest.hash, digest.size)))\n    }\n\n    /// Find and verify a stored object.\n    pub fn find(&self, digest: &CacheDigest) -> Result<Option<PathBuf>> {\n        let path = self.path_for(digest)?;\n        if !path.exists() {\n            return Ok(None);\n        }\n        if !digest.matches_file(&path)? {\n            bail!(\n                \"local CAS blob failed digest verification: {}\",\n                path.display()\n            );\n        }\n        Ok(Some(path))\n    }\n\n    /// Atomically store bytes after verifying their declared digest.\n    pub fn store_bytes(&self, digest: &CacheDigest, bytes: &[u8]) -> Result<PathBuf> {\n        if !digest.matches_bytes(bytes)? {\n            bail!(\"bytes do not match the declared CAS digest\");\n        }\n        self.store_with(digest, |temporary| {\n            temporary.write_all(bytes)?;\n            Ok(())\n        })\n    }\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/crates/mise-cache-core/src/local.rs#L31-L67","documentation":"LocalCas::find re-hashes a CAS file that already exists at the expected path (<root>/cas/v1/<algorithm>/<hash[0..2]>/<hash>-<size>) and compares it to the digest before returning it. A mismatch means on-disk corruption: the store refuses to hand back data that no longer matches its content-addressed key, and the message names the offending path.","triggerScenarios":"Anything mutating files under the CAS root after publication: disk corruption or bit rot, external processes editing cache files, a crash during a non-atomic write in an older version, or two cache layouts sharing one root.","commonSituations":"Users or cleanup tools writing inside the cache directory; failing disks; sharing a cache dir between mise versions with different layouts; antivirus or sync clients touching files; backup restores with altered metadata/content.","solutions":["Delete the blob file named in the error — the CAS is content-addressed and will repopulate it on demand","If corruption is widespread, remove the whole cache root and let it refill","Stop external tools (sync clients, editors, AV) from writing into the cache directory","Confirm the cache root is not shared between different cache formats or versions"],"exampleFix":"# before: cas.find(&digest) fails with\n#   local CAS blob failed digest verification: /home/u/.cache/mise/cas/v1/blake3/ab/abcd1234…-42\n\n# after: drop the corrupt blob (safe — it is content-addressed) and retry\nrm /home/u/.cache/mise/cas/v1/blake3/ab/abcd1234…-42","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let path = match cas.find(&digest) {\n    Ok(path) => path,\n    Err(report) if report.to_string().contains(\"digest verification\") => {\n        // corrupt on-disk blob: drop it (content-addressed, will be repopulated) -> miss\n        let _ = std::fs::remove_file(cas.path_for(&digest)?);\n        None\n    }\n    Err(report) => return Err(report),\n};","preventionTips":["Keep the cache root excluded from sync clients, editors, and antivirus","Do not share one cache root between different mise/cache versions","Treat single-blob verification failures as misses and delete the named file"],"tags":["cas","local-cache","corruption","digest-verification"],"backgroundTag":"cache-corruption","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}