{"record":{"id":"f26066ea498e3e59","repo":"jdx/mise","slug":"automatic-cross-platform-provisioning-refuses-to-r","errorCode":null,"errorMessage":"automatic cross-platform provisioning refuses to replace a custom mise build with an official binary because {} does not match the signed mise {} release checksums; set mise_bin, remote_mise, or bootstrap_command","messagePattern":"automatic cross-platform provisioning refuses to replace a custom mise build with an official binary because (.+?) does not match the signed mise (.+?) release checksums; set mise_bin, remote_mise, or bootstrap_command","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1043,"sourceCode":"            return Ok(());\n        }\n        if cfg!(debug_assertions) {\n            bail!(\n                \"automatic cross-platform provisioning is unavailable from a debug mise build; set mise_bin, remote_mise, or bootstrap_command\"\n            );\n        }\n        let local_os = normalize_os(std::env::consts::OS);\n        let local_arch = normalize_arch(std::env::consts::ARCH);\n        let candidates = official_release_assets(&local_os, &local_arch)?;\n        let actual = crate::hash::file_hash_sha256(local, None)?;\n        let manifest = self.manifest().await?;\n        let official = candidates.iter().any(|asset| {\n            manifest\n                .checksum(asset)\n                .is_ok_and(|expected| expected.eq_ignore_ascii_case(&actual))\n        });\n        if !official {\n            bail!(\n                \"automatic cross-platform provisioning refuses to replace a custom mise build with an official binary because {} does not match the signed mise {} release checksums; set mise_bin, remote_mise, or bootstrap_command\",\n                local.display(),\n                env!(\"CARGO_PKG_VERSION\")\n            );\n        }\n        self.official_local_verified = true;\n        Ok(())\n    }\n\n    async fn manifest(&mut self) -> Result<&ReleaseManifest> {\n        if self.manifest.is_none() {\n            let manifest_url = release_url(\"SHASUMS256.txt\");\n            let signature_url = release_url(\"SHASUMS256.txt.minisig\");\n            let (contents, signature) = tokio::try_join!(\n                HTTP.get_text_cached(&manifest_url),\n                HTTP.get_text_cached(&signature_url)\n            )\n            .wrap_err_with(|| {","sourceCodeStart":1025,"sourceCodeEnd":1061,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/remote.rs#L1025-L1061","documentation":"Thrown by RemoteArtifactResolver::ensure_official_local on a release build when the local mise binary's SHA-256 does not match any checksum for the local OS/arch assets in the signed SHASUMS256.txt manifest. Automatic cross-platform provisioning refuses to run from a binary it cannot prove is the official release, because the flow's security model is 'a signed official binary may fetch other signed official binaries'. Any locally compiled release build, distro-repackaged binary, patched/stripped binary, or corrupted file fails this gate.","triggerScenarios":"Running mise built with cargo build --release (byte-different from the official artifact), a distribution package build, a forked/patched mise, or a binary from a version whose local-arch asset name/checksum is not in the manifest, while reaching automatic artifact resolution (remote platform differs from local, no mise_bin/remote_mise/bootstrap_command set).","commonSituations":"Companies building internal mise forks; packagers testing remote bootstrap; users who rebuilt mise with different toolchain flags (different codegen = different hash); cached manifest vs newer binary version mismatch.","solutions":["Set mise_bin on the host entry to upload that exact custom binary instead of the official artifact","Set remote_mise or bootstrap_command to provision mise on the remote without involving the official artifact flow","Or run the genuine official mise release for CARGO_PKG_VERSION so the checksum matches"],"exampleFix":"# before (mise.toml)\n[bootstrap.remote.hosts.builder]\nhost = \"builder@aarch64-runner\"\n\n# after\n[bootstrap.remote.hosts.builder]\nhost = \"builder@aarch64-runner\"\nmise_bin = \"./target/release/mise\"  # upload this custom build explicitly","handlingStrategy":"fallback","validationCode":"# Pre-check before relying on automatic provisioning from a custom build:\n# the sha256 of your binary must equal the entry in the signed SHASUMS256.txt\nV=$(mise --version | awk '{print $2}')\nMYHASH=$(sha256sum \"$(command -v mise)\" | cut -d' ' -f1)\ncurl -fsSL \"https://github.com/jdx/mise/releases/download/v${V}/SHASUMS256.txt\" \\\n  | grep -qi \"^${MYHASH}\" || echo \"custom build: set mise_bin/remote_mise/bootstrap_command\"","typeGuard":"fn is_official_release_binary(local: &Path, manifest: &ReleaseManifest) -> bool {\n    let Ok(actual) = crate::hash::file_hash_sha256(local, None) else {\n        return false;\n    };\n    official_release_assets(&normalize_os(std::env::consts::OS), &normalize_arch(std::env::consts::ARCH))\n        .map(|assets| {\n            assets.iter().any(|a| {\n                manifest.checksum(a).is_ok_and(|c| c.eq_ignore_ascii_case(&actual))\n            })\n        })\n        .unwrap_or(false)\n}","tryCatchPattern":"match resolver.resolve(&platform, &local).await {\n    Err(e) if e.to_string().contains(\"does not match the signed mise\") => {\n        // deliberate fallback: upload the custom binary explicitly\n        upload_custom_binary(&host, &local).await?;\n    }\n    other => other?,\n}","preventionTips":["Treat any fork/rebuild of mise as needing mise_bin or bootstrap_command in host config","Keep official installs byte-pristine: no strip/patch/repack","Version-skew: after upgrading mise, re-verify automatic provisioning still works (manifest is per-version)"],"tags":["mise","remote-bootstrap","checksum","custom-build","provisioning"],"backgroundTag":"checksum-verification-failed","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}