jdx/mise · error

precompiled erlang is not supported on musl linux

Error message

precompiled erlang is not supported on musl linux

What it means

mise refuses precompiled Erlang on musl libc because Bob the Builder (builds.hex.pm) publishes OTP binaries only for glibc Ubuntu. linux_precompiled_base_url bails as soon as the target's libc is musl. It only becomes a hard error when erlang.compile=false; otherwise it demotes to a fallback reason and mise compiles OTP from source with kerl (a long build requiring a C toolchain).

Source

Thrown at src/plugins/core/erlang.rs:168

            Self::release_tag(version),
            Self::source_asset_name(version)
        )
    }

    fn source_archive_url(version: &str) -> String {
        format!(
            "https://github.com/erlang/otp/archive/{}.tar.gz",
            Self::release_tag(version)
        )
    }

    fn source_cache_name(url: &str) -> String {
        format!("otp-source-{}.tar.gz", crate::hash::hash_sha256_to_str(url))
    }

    fn linux_precompiled_base_url(target: &PlatformTarget) -> Result<String> {
        if target.libc() == Some("musl") {
            bail!("precompiled erlang is not supported on musl linux");
        }
        let arch = match target.arch_name() {
            "x64" => "amd64",
            "arm64" => "arm64",
            other => bail!("unsupported architecture: {other}"),
        };
        let os_ver = Self::linux_precompiled_os_version()?;
        Ok(format!("https://builds.hex.pm/builds/otp/{arch}/{os_ver}"))
    }

    async fn linux_precompiled_lock_info(
        version: &str,
        target: &PlatformTarget,
    ) -> Result<PlatformInfo> {
        let base_url = Self::linux_precompiled_base_url(target)?;
        let release_tag = Self::release_tag(version);
        let builds = HTTP_FETCH
            .get_text_cached(format!("{base_url}/builds.txt"))

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Enable source builds: `mise settings set erlang.compile true`, and install build deps first (on Alpine: `apk add make gcc g++ ncurses-dev openssl-dev`) so kerl can build OTP
  2. Switch to a glibc base image (debian/ubuntu) instead of Alpine if you want precompiled OTP
  3. On Alpine specifically, consider the distro package (`apk add erlang`) and stop managing Erlang with mise there

Example fix

# before
FROM alpine:3.20
RUN mise install erlang@27.1   # musl → no precompiled OTP, hard error with compile=false

# after
FROM ubuntu:24.04
RUN mise install erlang@27.1   # glibc → hex.pm precompiled build works
Defensive patterns

Strategy: validation

Validate before calling

# fail fast (or switch policy) before mise touches erlang on musl
if ldd --version 2>&1 | head -1 | grep -q musl; then
  mise settings set erlang.compile true   # or exit with a clear message
fi
mise install erlang@27.1

Type guard

is_musl() { ldd --version 2>&1 | head -1 | grep -q musl; }

Prevention

When it happens

Trigger: `mise install erlang` on Alpine (or any musl distro — `ldd --version` reports musl), with erlang.compile unset (silent fallback into a long source build) or explicitly false (this error). Also reachable during `mise lock` with compile=false, since lock resolution calls the same base-URL helper.

Common situations: Teams moving CI from Debian/Ubuntu images to Alpine for smaller containers; developers on Alpine WSL or NixOS with musl shells hitting either a surprise 20-minute compile or this hard failure.

Related errors


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