{"record":{"id":"75a51508cf1c8013","repo":"jdx/mise","slug":"codesign-failed-for","errorCode":null,"errorMessage":"codesign failed for {}: {}","messagePattern":"codesign failed for (.+?): (.+?)","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/relocate.rs","lineNumber":307,"sourceCode":"/// the kernel kills binaries whose signature doesn't match their contents.\npub fn codesign(files: &[PathBuf]) -> Result<()> {\n    for file in files {\n        let res = crate::cmd::cmd(\n            \"/usr/bin/codesign\",\n            [\n                \"--sign\",\n                \"-\",\n                \"--force\",\n                \"--preserve-metadata=entitlements,requirements,flags,runtime\",\n                &file.to_string_lossy(),\n            ],\n        )\n        .stderr_capture()\n        .stdout_capture()\n        .unchecked()\n        .run()?;\n        if !res.status.success() {\n            bail!(\n                \"codesign failed for {}: {}\",\n                file.display(),\n                String::from_utf8_lossy(&res.stderr).trim()\n            );\n        }\n    }\n    Ok(())\n}\n\n#[cfg(test)]\npub(super) mod tests {\n    use super::*;\n    use std::io::{Cursor, Read, Write};\n    use std::os::unix::fs::PermissionsExt;\n\n    /// fixed macOS-style replacements so tests behave the same on all hosts\n    pub(in super::super) fn test_replacements() -> Vec<Replacement> {\n        vec![","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/packages/brew/relocate.rs#L289-L325","documentation":"On macOS (notably Apple Silicon), after patching binaries during relocation mise re-applies an ad-hoc code signature with `codesign --sign - --force --preserve-metadata=...`. If codesign exits nonzero, the error carries its stderr. Aborting is correct: an unsigned or malformed arm64 binary would be killed by the kernel on next launch anyway.","triggerScenarios":"run_codesign executes after relocation on arm64 macOS; codesign fails because the patched Mach-O is malformed (corrupt download), entitlements/requirements cannot be preserved, or the codesign tool itself is broken (damaged Xcode CLT).","commonSituations":"Corrupt or truncated bottle downloads making the Mach-O invalid; macOS upgrades leaving Command Line Tools broken; CI hosts with security policies restricting codesign; binaries whose embedded provisioning data cannot be re-signed ad hoc.","solutions":["Read the included stderr — it names the specific codesign complaint (invalid Mach-O, unsupported format, etc.)","Clear mise's brew bottle cache to force a clean re-download in case of corruption","Verify manually with `codesign -vv <file>`; if codesign itself is broken, reinstall Xcode Command Line Tools","Fall back to installing the formula with native Homebrew on that machine"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match relocate_and_sign(...).await {\n    Err(e) if e.to_string().contains(\"codesign failed\") => {\n        // clear the suspect bottle, retry once; if it still fails, install with native brew\n        crate::file::remove_all(&bottle_path).ok();\n        relocate_and_sign(...).await.map_err(|e| e.wrap_err(\"codesign still failing — reinstall Xcode CLT or use native brew\"))\n    }\n    other => other,\n}","preventionTips":["Keep Xcode Command Line Tools healthy (`xcode-select --install`) on arm64 macOS hosts","Clear mise's bottle cache after interrupted downloads so corrupt Mach-Os are re-fetched","On CI runners with codesign restrictions, install brew packages with native Homebrew instead"],"tags":["macos","codesign","arm64","brew","relocation"],"backgroundTag":"macos-codesign-failure","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}