{"record":{"id":"9449473599efca8c","repo":"jdx/mise","slug":"signed-mise-release-checksum-manifest-contains-an","errorCode":null,"errorMessage":"signed mise release checksum manifest contains an invalid SHA-256 checksum","messagePattern":"signed mise release checksum manifest contains an invalid SHA-256 checksum","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1481,"sourceCode":"    }\n}\n\nimpl ReleaseManifest {\n    fn verified(contents: &str, signature: &str) -> Result<Self> {\n        crate::minisign::verify(\n            &crate::minisign::MISE_PUB_KEY,\n            contents.as_bytes(),\n            signature,\n        )\n        .wrap_err(\"mise release checksum signature is invalid\")?;\n        let checksums = crate::hash::parse_shasums(contents);\n        if checksums.is_empty() {\n            bail!(\"signed mise release checksum manifest is empty\");\n        }\n        if checksums.values().any(|checksum| {\n            checksum.len() != 64 || !checksum.bytes().all(|byte| byte.is_ascii_hexdigit())\n        }) {\n            bail!(\"signed mise release checksum manifest contains an invalid SHA-256 checksum\");\n        }\n        Ok(Self { checksums })\n    }\n\n    fn checksum(&self, asset: &str) -> Result<&str> {\n        self.checksums\n            .get(asset)\n            .or_else(|| self.checksums.get(&format!(\"./{asset}\")))\n            .map(String::as_str)\n            .ok_or_else(|| eyre!(\"signed mise release manifest does not contain {asset}\"))\n    }\n}\n\nimpl RemoteArtifactResolver {\n    async fn resolve(&mut self, platform: &RemotePlatform, local: &Path) -> Result<PathBuf> {\n        let asset = platform.release_asset_name()?;\n        if let Some(path) = self.artifacts.get(&asset) {\n            return Ok(path.clone());","sourceCodeStart":1463,"sourceCodeEnd":1499,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/remote.rs#L1463-L1499","documentation":"After verifying the signature of mise's SHA256SUMS manifest, `ReleaseManifest::verified` validates every checksum value: each must be exactly 64 ASCII hex digits (a valid SHA-256 hex digest). If any entry fails that shape — wrong length or non-hex characters — the manifest cannot be trusted for byte-for-byte verification and this error is thrown.","triggerScenarios":"A signed manifest whose checksum column is malformed: truncated digests, uppercase-inconsistent or non-hex characters (e.g. 'sha256-...' base64 digests instead of hex), or an upstream tooling change in how checksums are written.","commonSituations":"Upstream switched checksum format (e.g. minisign/concatenated formats), a corrupted manifest served by a mirror, or a parser mis-splitting lines so only part of the digest is captured.","solutions":["Confirm the mise release's SHA256SUMS asset actually contains 64-char hex digests (inspect it manually).","Retry from a different mirror/network in case the manifest was corrupted in transit.","Upgrade or downgrade mise — a parser/format mismatch may be fixed in another release.","Set `mise_bin`, `remote_mise`, or `bootstrap_command` to skip signed-manifest verification."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# shell: sanity-check manifest shape before trusting it\nawk 'NF && $1 !~ /^[0-9a-fA-F]{64}$/ {print \"bad digest:\", $1; exit 1}' SHA256SUMS","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fetch manifests only from the official release URL, not mirrors.","Keep mise updated so manifest parsing matches upstream format.","Report persistent failures — likely an upstream format change."],"tags":["security","checksum","sha256","validation"],"backgroundTag":"checksum-mismatch","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}