{"record":{"id":"99f7ced811fc7a0c","repo":"jdx/mise","slug":"signature-does-not-match-any-trusted-public-key","errorCode":null,"errorMessage":"signature does not match any trusted public key","messagePattern":"signature does not match any trusted public key","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/gpg.rs","lineNumber":63,"sourceCode":"        bail!(\"no signature found to verify\");\n    }\n\n    // Fast path: only try keys whose id/fingerprint matches the signature's issuer, so the signed\n    // content is hashed at most once in the common case.\n    for sig in &signatures {\n        if verify_against_keys(sig, &keys, &open_data, true)? {\n            return Ok(());\n        }\n    }\n    // Fallback: try every trusted key, but only for signatures that carried no usable issuer\n    // hint. A signature that named an issuer we don't trust is genuinely unverifiable, so skip it\n    // rather than re-hashing the (potentially large) content against every key.\n    for sig in signatures.iter().filter(|sig| !has_issuer(&sig.signature)) {\n        if verify_against_keys(sig, &keys, &open_data, false)? {\n            return Ok(());\n        }\n    }\n    bail!(\"signature does not match any trusted public key\");\n}\n\nfn verify_against_keys<R, F>(\n    sig: &DetachedSignature,\n    keys: &[SignedPublicKey],\n    open_data: &F,\n    require_issuer_match: bool,\n) -> Result<bool>\nwhere\n    R: Read,\n    F: Fn() -> Result<R>,\n{\n    for key in keys {\n        if (!require_issuer_match\n            || issuer_matches(&sig.signature, &key.fingerprint(), &key.legacy_key_id()))\n            && try_verify(sig, key, open_data)?\n        {\n            return Ok(true);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/gpg.rs#L45-L81","documentation":"mise verifies downloaded archives against a detached GPG signature using a set of trusted public keys. After trying every candidate signature against every trusted key, if none verifies, verify_detached bails with this error. It means the artifact's signature could not be validated by any key mise trusts.","triggerScenarios":"Calling verify_detached (via verify_node, verify_swift, or verify_swift_bytes) on a downloaded file whose detached signature is invalid, signed by an untrusted/unknown key, corrupted in transit, or stripped of its issuer subpacket so it can't be matched to a key.","commonSituations":"Mirror or proxy serving a re-signed or tampered node/swift tarball; download truncation corrupting the .sig file; upstream changed signing keys while local trusted keys are stale; fetching a nightly/RC artifact that isn't signed the same way as releases.","solutions":["Re-download the artifact and its signature (delete the cached download and retry the install) — corruption is the most common cause.","Verify the artifact's signing key against upstream key IDs and add/update trusted keys in the local key set if upstream rotated keys.","Check that you're fetching artifacts from official sources, not a proxy that re-signs or re-packages them.","Confirm the signature file is complete and matches the exact bytes being verified (same version/platform archive)."],"exampleFix":"// before: retrying against a corrupted cached download\nmise install node@22.0.0   // fails: signature does not match any trusted public key\n// after: clear the corrupt download cache and reinstall\nrm -rf ~/.cache/mise/node/archive/v22.0.0* && mise install node@22.0.0","handlingStrategy":"validation","validationCode":"# before install, verify the artifact+sig pair is intact\nsig_bytes=$(curl -fsSL \"$SIG_URL\") && echo \"signature fetched: ${#sig_bytes} bytes\" || echo \"signature missing/corrupt\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Download artifacts only from official sources/mirrors that preserve signatures byte-for-byte","When upstream rotates signing keys, update trusted keys before installing new releases","Delete cached downloads after failed installs so corrupted artifacts aren't reused"],"tags":["gpg","signature-verification","download","security"],"backgroundTag":"checksum-mismatch","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}