zeroclaw-labs/zeroclaw · error · anyhow::Error

architecture mismatch: downloaded binary is {bin} but this h

Error message

architecture mismatch: downloaded binary is {bin} but this host is {host} — the release asset may be mispackaged

What it means

check_binary_arch compares the machine type detected from the staged binary's header (detect_arch_from_header) with the running host's architecture (host_architecture). When both are known and differ, the updater refuses to install a binary the host cannot execute, naming both architectures and flagging a possibly mispackaged release asset. If either side is unknown, the check is skipped.

Source

Thrown at src/commands/update.rs:757

    tokio::fs::File::open(path)
        .await
        .context("failed to open binary to read header")?
        .take(4096)
        .read_to_end(&mut header)
        .await
        .context("failed to read binary header")?;

    if header.len() < 20 {
        bail!("downloaded file too small to be a valid binary");
    }

    let binary_arch = detect_arch_from_header(&header);
    let host_arch = host_architecture();

    if let (Some(bin), Some(host)) = (binary_arch, host_arch)
        && bin != host
    {
        bail!(
            "architecture mismatch: downloaded binary is {bin} but this host is {host} — \
             the release asset may be mispackaged"
        );
    }

    Ok(())
}

fn detect_arch_from_header(header: &[u8]) -> Option<&'static str> {
    // ELF magic: 0x7f 'E' 'L' 'F'
    if header.len() >= 20 && header[0..4] == [0x7f, b'E', b'L', b'F'] {
        // e_machine is at offset 18 (2 bytes, little-endian for LE binaries)
        let e_machine = u16::from_le_bytes([header[18], header[19]]);
        return match e_machine {
            0x3E => Some("x86_64"),
            0xB7 => Some("aarch64"),
            0x03 => Some("x86"),
            0x28 => Some("arm"),

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Check the host architecture with `uname -m` (or `arch` on macOS) and confirm which asset the updater selected from the error text (it names both).
  2. If the asset for your arch is mispackaged, report the release and pin the previous known-good version.
  3. On Apple Silicon, verify the darwin-aarch64 asset is the one being downloaded rather than the x86_64 one.
  4. If you drive asset selection yourself, map platform to asset explicitly instead of relying on defaults.
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight: match host arch to the asset you let the updater pick
host="$(uname -m)"   # x86_64 / aarch64
case "$host" in
  x86_64)  asset='zeroclaw-x86_64-*.tar.gz' ;;
  aarch64) asset='zeroclaw-aarch64-*.tar.gz' ;;
  *) echo "unsupported host arch: $host" >&2; exit 1 ;;
esac

Try / catch

match run_update().await {
    Err(e) if e.to_string().starts_with("architecture mismatch") => {
        // wrong-arch asset: stop and correct platform selection; never force install
    }
    other => other,
}

Prevention

When it happens

Trigger: `zeroclaw update` when the selected release asset contains a binary for a different machine type than the host: x86_64 host receiving an aarch64 binary, Apple Silicon receiving an x86_64 asset, or a correctly-named asset packed with the wrong-arch binary inside.

Common situations: Asset-selection logic picking the wrong platform tuple (musl/gnu, darwin intel/arm64); running under Rosetta or an emulation layer where host identity is ambiguous; release packaging mixing up per-arch artifacts; manually forcing a platform override.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/93ed6d2b60ca3f8a. Report an issue: GitHub.