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
- 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
- Switch to a glibc base image (debian/ubuntu) instead of Alpine if you want precompiled OTP
- 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
- Standardize CI images on glibc (debian/ubuntu) when precompiled OTP is required
- In Dockerfiles, add a comment at the FROM line noting mise erlang needs glibc
- If Alpine is mandatory, budget build time and install the gcc/ncurses/openssl dev packages up front
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
- precompiled erlang is not available: {reason}
- unsupported architecture: {other}
- unsupported OS version: {os_ver}
- precompiled erlang is not supported on {os}
- expected exactly one Hex OTP build record for {release_tag},
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/693d83f951f66ac9.
Report an issue: GitHub.