jdx/mise · error

precompiled erlang is not supported on musl linux

Error message

precompiled erlang is not supported on musl linux

What it means

Precompiled Erlang builds from Hex (Bob) are not published for musl-linked Linux (Alpine, etc.). When resolving the download base URL for the target platform, mise refuses up front if the target libc is musl.

Solutions

  1. Compile from source (ensure erlang_compile is enabled; install build deps gcc, make, openssl-dev, ncurses)
  2. Use a glibc-based base image (debian/ubuntu) for precompiled builds
  3. Find a musl precompiled build via a different backend or kerl/asdf plugin

Example fix

# before
FROM alpine:3.19
RUN mise install erlang@26.2
# after
FROM debian:bookworm
RUN mise install erlang@26.2
Defensive patterns

Strategy: fallback

Validate before calling

# guard before install
[ "$(ldd --version 2>/dev/null | grep -c musl)" = "0" ] && echo "glibc: precompiled OK" || echo "musl: needs compile"

Try / catch

catch (e) {
  if (/musl linux/.test(String(e))) {
    // fall back to source compile or glibc image
  }
}

Prevention

When it happens

Trigger: `mise install erlang@<version>` on a musl Linux system (or targeting musl) with source compilation not explicitly disabled — precompiled_unavailable then reports this reason or falls back to compile.

Common situations: Alpine Linux containers/CI images; musl-based Dockerfiles trying to precompile-install Erlang quickly.

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/693d83f951f66ac9. Report an issue: GitHub.

Appendix: 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 533346cc37)