jdx/mise · error · eyre::Report

remote host '{}' libc {remote_libc:?} is incompatible with l

Error message

remote host '{}' libc {remote_libc:?} is incompatible with local mise libc {local_libc:?}; set mise_bin, remote_mise, or bootstrap_command

What it means

Thrown by validate_default_binary_compatibility when the remote DOES have the loader path the local mise binary requests, but running '<loader> --version' on the remote reports a different libc family than the local one (glibc vs musl). It is the flavor-level companion of the loader-missing check: the interpreter exists (often via a compat package) yet the libc it implements differs, so the uploaded binary would crash or misbehave.

Source

Thrown at src/system/remote.rs:1254

    );
    let remote_output = session.output(&["sh", "-c", &check])?;
    if remote_output
        .lines()
        .any(|line| line == "MISE_LOADER_MISSING")
    {
        bail!(
            "remote host '{}' does not provide the dynamic loader required by local mise: {interpreter}; set mise_bin, remote_mise, or bootstrap_command",
            session.host.name
        );
    }
    let remote_libc = parse_libc_flavor(&remote_output).ok_or_else(|| {
        eyre!(
            "could not identify the libc provided by remote loader {interpreter} on '{}'; set mise_bin, remote_mise, or bootstrap_command",
            session.host.name
        )
    })?;
    if local_libc != remote_libc {
        bail!(
            "remote host '{}' libc {remote_libc:?} is incompatible with local mise libc {local_libc:?}; set mise_bin, remote_mise, or bootstrap_command",
            session.host.name
        );
    }
    let required = match local_libc {
        LibcFlavor::Glibc => max_required_glibc_version(&binary_bytes).ok_or_else(|| {
            eyre!(
                "could not determine the glibc ABI required by local mise; set mise_bin, remote_mise, or bootstrap_command"
            )
        })?,
        LibcFlavor::Musl => parse_musl_runtime_version(&combined_output(&local_output))
            .ok_or_else(|| {
                eyre!(
                    "could not determine the musl version used by local mise loader {interpreter}; set mise_bin, remote_mise, or bootstrap_command"
                )
            })?,
    };
    let available = match remote_libc {

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Remove the explicit local upload: use bootstrap_command (official install script fetches a remote-matched artifact) or remote_mise
  2. Use mise_bin pointing at a binary linked against the remote's actual libc (musl build for musl hosts)
  3. Drop the compat aliases on the remote so detection is honest, then rely on official artifact download

Example fix

# before (mise.toml)
[bootstrap.remote.hosts.edge]
host = "ops@edge"
mise_bin = "./mise-glibc"  # remote loader at same path is musl via gcompat

# after
[bootstrap.remote.hosts.edge]
host = "ops@edge"
bootstrap_command = "curl -fsSL https://mise.run | sh"
Defensive patterns

Strategy: fallback

Validate before calling

# Compare libc families explicitly before relying on local-binary upload:
local=$(ldd --version | head -1 | tr '[:upper:]' '[:lower:]')
remote=$(ssh ops@edge 'ldd --version 2>&1 | head -1' | tr '[:upper:]' '[:lower:]')
for f in glibc musl; do
  case "$local" in *$f*) case "$remote" in *$f*) echo "family ok: $f";; *) echo "family mismatch: use bootstrap_command";; esac;; esac
done

Type guard

fn libc_families_match(local_out: &str, remote_out: &str) -> bool {
    parse_libc_flavor(local_out).is_some_and(|l| parse_libc_flavor(remote_out) == Some(l))
}

Try / catch

match validate_default_binary_compatibility(&session, &binary, "linux").await {
    Err(e) if e.to_string().contains("libc") && e.to_string().contains("incompatible") => {
        resolver.resolve(&platform, &binary).await?; // official remote artifact instead
    }
    other => other?,
}

Prevention

When it happens

Trigger: Local glibc mise pushed to a remote that ships a musl loader at the glibc path (or vice versa) through a compatibility layer; mixed-libc systems with aliased loader paths.

Common situations: Remotes with gcompat/musl-compat packages exposing alien loader paths; hand-symlinked loaders by admins trying to run foreign binaries.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/290e080a4e358b7d. Report an issue: GitHub.