{"record":{"id":"e3a2891684a83bf3","repo":"jdx/mise","slug":"remote-host-provides-remote-libc-availab","errorCode":null,"errorMessage":"remote host '{}' provides {remote_libc:?} {available}, but local mise requires {remote_libc:?} {required}; set mise_bin, remote_mise, or bootstrap_command","messagePattern":"remote host '(.+?)' provides (.+?) (.+?), but local mise requires (.+?) (.+?); set mise_bin, remote_mise, or bootstrap_command","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1283,"sourceCode":"        LibcFlavor::Musl => parse_musl_runtime_version(&combined_output(&local_output))\n            .ok_or_else(|| {\n                eyre!(\n                    \"could not determine the musl version used by local mise loader {interpreter}; set mise_bin, remote_mise, or bootstrap_command\"\n                )\n            })?,\n    };\n    let available = match remote_libc {\n        LibcFlavor::Glibc => parse_glibc_runtime_version(&remote_output),\n        LibcFlavor::Musl => parse_musl_runtime_version(&remote_output),\n    }\n    .ok_or_else(|| {\n        eyre!(\n            \"could not determine the {remote_libc:?} version provided by remote loader {interpreter} on '{}'; set mise_bin, remote_mise, or bootstrap_command\",\n            session.host.name\n        )\n    })?;\n    if available < required {\n        bail!(\n            \"remote host '{}' provides {remote_libc:?} {available}, but local mise requires {remote_libc:?} {required}; set mise_bin, remote_mise, or bootstrap_command\",\n            session.host.name\n        );\n    }\n    Ok(())\n}\n\nfn max_required_glibc_version(bytes: &[u8]) -> Option<AbiVersion> {\n    const PREFIX: &[u8] = b\"GLIBC_\";\n    bytes\n        .windows(PREFIX.len())\n        .enumerate()\n        .filter_map(|(offset, window)| {\n            (window == PREFIX)\n                .then(|| parse_abi_version(&bytes[offset + PREFIX.len()..]))\n                .flatten()\n        })\n        .max()","sourceCodeStart":1265,"sourceCodeEnd":1301,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/remote.rs#L1265-L1301","documentation":"Thrown by validate_default_binary_compatibility when the remote loader exists and matches the local libc family, but its version is older than what the local mise binary requires. The required glibc is computed by scanning the binary for the highest GLIBC_x.y symbol-version reference (max_required_glibc_version); for musl the local loader's runtime version is used. This is the preflight equivalent of the classic \"version GLIBC_2.38 not found\" crash, caught before upload.","triggerScenarios":"Building/uploading mise from a new distro (Ubuntu 24.04, Fedora 40) to an old remote (CentOS 7, Ubuntu 16.04/18.04, RHEL 7) whose glibc predates the binary's newest referenced symbol; old musl on embedded remotes.","commonSituations":"Enterprise fleets pinned to old LTS releases; IoT gateways with vendor-old toolchains; developer workstations far newer than production images.","solutions":["Use bootstrap_command with the official install script so the remote gets an artifact built for its own platform, not your local binary","Set mise_bin to a binary built against an old glibc (manylinux-style toolchain) or a musl static-ish build","Upgrade the remote's libc/distro so its loader meets the required version"],"exampleFix":"# before (mise.toml)\n[bootstrap.remote.hosts.legacy]\nhost = \"root@centos7\"\nmise_bin = \"./mise-built-on-ubuntu-24\"  # needs GLIBC_2.38, remote has 2.17\n\n# after\n[bootstrap.remote.hosts.legacy]\nhost = \"root@centos7\"\nbootstrap_command = \"curl -fsSL https://mise.run | sh\"","handlingStrategy":"fallback","validationCode":"# Compute the binary's max GLIBC requirement and compare with the remote loader:\nREQ=$(readelf -V ./mise 2>/dev/null | grep -o 'GLIBC_[0-9.]*' | sort -V | tail -1)\nREM=$(ssh root@centos7 '/lib64/ld-linux-x86-64.so.2 --version' | grep -o '[0-9]\\+\\.[0-9]\\+$' | head -1)\n[ \"$(printf '%s\\n' \"$REM\" \"$REQ\" | sort -V | tail -1)\" = \"$REM\" ] \\\n  && echo \"glibc ok\" || echo \"remote too old ($REM < $REQ): use bootstrap_command or musl build\"","typeGuard":"fn remote_libc_new_enough(required: &AbiVersion, remote_loader_output: &str) -> bool {\n    parse_glibc_runtime_version(remote_loader_output)\n        .is_some_and(|available| available >= *required)\n}","tryCatchPattern":"match validate_default_binary_compatibility(&session, &binary, \"linux\").await {\n    Err(e) if e.to_string().contains(\"but local mise requires\") => {\n        resolver.resolve(&platform, &binary).await?; // download artifact matched to remote\n    }\n    other => other?,\n}","preventionTips":["Build once against the oldest glibc in your fleet (manylinux-style) or ship musl builds","Prefer bootstrap_command (remote-side install) over uploading workstation builds to old LTS hosts","Track the fleet's minimum glibc version; fail CI uploads that exceed it"],"tags":["mise","remote-bootstrap","glibc","symbol-version","abi","old-distro","compatibility"],"backgroundTag":"glibc-version-too-old","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}