jdx/mise · error

no dynamic linker found for

Error message

no dynamic linker found for {ld} — Homebrew bottles require glibc (musl-based distros are unsupported)

What it means

On Linux, Homebrew bottles are glibc-linked and mise's prefix setup must provide a dynamic linker (ld.so) inside the brew prefix. setup_linux_runtime searches for a host glibc loader at the standard paths (/lib64/ld-linux-x86-64.so.2, /lib/ld-linux-aarch64.so.1, etc.) and bails when none exists, since musl-based distros (Alpine, musl Void) cannot run glibc bottles without a brewed glibc.

Solutions

  1. Install glibc on the host (e.g. Alpine's `apk add glibc` via the gcompat/glibc packages or use a glibc-based base image like debian/ubuntu)
  2. Let mise brew a glibc keg first so the loader can be taken from Cellar/glibc (ensure the glibc formula can be installed)
  3. Use a non-brew backend for packages on musl systems (apk-compatible tools, or github:/cargo: backends)

Example fix

// Dockerfile before
FROM alpine:3.20
// after
FROM debian:bookworm-slim  # or apk add --allow-untrusted glibc on alpine
Defensive patterns

Strategy: validation

Validate before calling

[ -x /lib64/ld-linux-x86-64.so.2 ] || [ -x /lib/ld-linux-aarch64.so.1 ] \
  || echo "no glibc loader — brew bottles unsupported on this (musl?) system"

Prevention

When it happens

Trigger: Running brew package installation on Linux where no host glibc dynamic linker exists at the checked paths — typically a musl-based distribution (Alpine Linux) or a heavily stripped container without glibc and no brewed glibc keg.

Common situations: Alpine/musl containers or CI images; distroless golang/alpine base images where someone enabled the brew backend; minimal chroots lacking /lib64.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/1212cc26b354cdd5. Report an issue: GitHub.

Appendix: source

Thrown at src/system/packages/brew/prefix.rs:115

        return Ok(());
    }
    if ld.exists() {
        return Ok(()); // valid symlink or file already in place
    }
    if ld.symlink_metadata().is_ok() {
        crate::file::remove_file(&ld)?; // dangling symlink
    }
    let host_loader = [
        "/lib64/ld-linux-x86-64.so.2",
        "/lib/ld-linux-aarch64.so.1",
        "/lib64/ld-linux-aarch64.so.1",
    ]
    .iter()
    .map(Path::new)
    .find(|p| p.exists())
    .map(Path::to_path_buf);
    let Some(target) = host_loader else {
        bail!(
            "no dynamic linker found for {} — Homebrew bottles require glibc (musl-based \
             distros are unsupported)",
            ld.display()
        );
    };
    crate::file::make_symlink(&target, &ld)?;
    Ok(())
}

fn writable(path: &Path) -> bool {
    // root can write regardless of owner — and `sudo mise` must never treat
    // a user-owned prefix as broken and chown it to root
    if nix::unistd::geteuid().is_root() {
        return path.exists();
    }
    !matches!(
        path.metadata()
            .map(|m| std::os::unix::fs::MetadataExt::uid(&m)),

View on GitHub (pinned to 533346cc37)