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

downloaded binary --version check failed

Error message

downloaded binary --version check failed

What it means

As part of validate_binary, the updater executes the freshly downloaded binary with --version. The process spawned successfully (unlike the 'cannot execute downloaded binary' context error) but exited with a non-zero status. This usually means the binary runs but crashes on startup because the host cannot satisfy its runtime dependencies.

Source

Thrown at src/commands/update.rs:721

        bail!(
            "downloaded binary too small ({} bytes), likely corrupt",
            meta.len()
        );
    }

    // Check binary architecture before attempting execution so we can give
    // a clear diagnostic instead of the opaque "Exec format error (os error 8)".
    check_binary_arch(path).await?;

    // Quick check: try running --version
    let output = tokio::process::Command::new(path)
        .arg("--version")
        .output()
        .await
        .context("cannot execute downloaded binary")?;

    if !output.status.success() {
        bail!("downloaded binary --version check failed");
    }

    let stdout = String::from_utf8_lossy(&output.stdout);
    if !stdout.contains("zeroclaw") {
        bail!("downloaded binary does not appear to be zeroclaw");
    }

    Ok(())
}

async fn check_binary_arch(path: &Path) -> Result<()> {
    use tokio::io::AsyncReadExt;

    // Read only the header — enough to cover a PE file's DOS stub and reach the
    // COFF machine field pointed to by `e_lfanew` (well under 4 KiB in practice)
    // — instead of pulling the whole multi-megabyte binary into memory.
    let mut header = Vec::new();
    tokio::fs::File::open(path)

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Run the downloaded binary directly with --version from a shell to read the real stderr (e.g. '/lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.xx not found').
  2. Check your glibc version with `ldd --version`; if it is older than the release requires, use a musl/static asset if the release provides one.
  3. Install missing runtime libraries the error names.
  4. Report the platform combination (OS, arch, glibc) against the release so packaging can cover it.
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-flight: can this host run the release binary at all?
curl -fsSL <asset-url> -o /tmp/zeroclaw-test && chmod +x /tmp/zeroclaw-test
/tmp/zeroclaw-test --version >/dev/null || echo 'host cannot run this build' >&2

Try / catch

match run_update().await {
    Err(e) if e.to_string().contains("--version check failed") => {
        // run the staged binary manually to capture stderr; typically a
        // glibc/library problem: switch asset (musl) or update the host
    }
    other => other,
}

Prevention

When it happens

Trigger: `zeroclaw update` on a host where the downloaded binary starts then fails: glibc older than the release was built against, missing shared libraries, CPU without required instruction sets, or a sandbox restricting the child process.

Common situations: Old Debian/Ubuntu or RHEL base images with old glibc (binary built on a newer toolchain); missing libssl/libgcc at runtime; hardened sandboxes (seccomp/AppArmor) killing the child; gnu asset used on a host that needs the musl asset.

Related errors


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