jdx/mise · error
invalid Hex OTP checksum for {release_tag}: {checksum}
Error message
invalid Hex OTP checksum for {release_tag}: {checksum} What it means
The matched builds.txt line's 4th whitespace-separated field must be a 64-character lowercase hex sha256. This error fires when the field exists but fails that format — realistically a corrupted or hijacked builds.txt: a proxy/captive portal returning an HTML page that got stored by mise's text cache, a truncated download, or an upstream hex.pm format change. Fatal with erlang.compile=false, otherwise falls back to source.
Source
Thrown at src/plugins/core/erlang.rs:815
.lines()
.filter_map(|line| {
let parts = line.split_whitespace().collect::<Vec<_>>();
(parts.first() == Some(&release_tag)).then_some(parts)
})
.collect::<Vec<_>>();
if matching.len() != 1 {
bail!(
"expected exactly one Hex OTP build record for {release_tag}, found {}",
matching.len()
);
}
let checksum = matching[0]
.get(3)
.ok_or_else(|| eyre::eyre!("Hex OTP build record for {release_tag} has no checksum"))?;
if !regex!(r"^[0-9a-f]{64}$").is_match(checksum) {
bail!("invalid Hex OTP checksum for {release_tag}: {checksum}");
}
Ok(format!("sha256:{checksum}"))
}
#[cfg(any(linux, test))]
fn require_locked_precompiled_checksum(version: &str, checksum: Option<&str>) -> Result<String> {
let checksum = checksum.ok_or_else(|| {
eyre::eyre!(
"No lockfile checksum found for precompiled Erlang/OTP {version}; regenerate mise.lock with `mise lock`"
)
})?;
if !regex!(r"^sha256:[0-9a-f]{64}$").is_match(checksum) {
bail!(
"Invalid lockfile checksum for precompiled Erlang/OTP {version}; regenerate mise.lock with `mise lock`"
);
}
View on GitHub (pinned to 6f52dcdf99)
Solutions
- Inspect the live file: `curl -sSL https://builds.hex.pm/builds/otp/amd64/ubuntu-24.04/builds.txt | head -3` — if it is HTML, fix the network/proxy
- Clear mise's HTTP cache and retry: `mise cache` (or remove the cache dir shown by `mise cache dir`)
- Bypass TLS interception for builds.hex.pm in the proxy profile
- Workaround: `mise settings set erlang.compile true` to skip the builds.txt path entirely
Example fix
# before $ mise install erlang@27.1 ERROR: invalid Hex OTP checksum for OTP-27.1: <html>... # after $ curl -sSL https://builds.hex.pm/builds/otp/amd64/ubuntu-24.04/builds.txt | head -1 # confirm real data $ mise cache # drop poisoned cache $ mise install erlang@27.1
Defensive patterns
Strategy: retry
Validate before calling
# sanity-check the live builds.txt payload before relying on it
curl -fsSL https://builds.hex.pm/builds/otp/amd64/ubuntu-24.04/builds.txt \
| grep -E '^OTP-[^ ]+ .+ [0-9a-f]{64}$' >/dev/null \
|| { echo 'builds.txt malformed (proxy/CDN issue?)'; exit 1; } Try / catch
if ! mise install erlang@27.1; then
if mise install erlang@27.1 2>&1 | grep -q 'invalid Hex OTP checksum'; then
mise cache # drop poisoned text cache, then retry once
mise install erlang@27.1
fi
fi Prevention
- Exclude builds.hex.pm from TLS-inspecting proxies
- When a checksum-format error appears right after a network change, suspect the cached builds.txt first
When it happens
Trigger: `mise install erlang` (compile=false) behind a corporate TLS-intercepting proxy that serves an error page for builds.hex.pm; a stale cached builds.txt from a partial fetch; upstream temporarily serving a malformed file.
Common situations: Corporate networks with SSL inspection; hotel/airport captive portals poisoning caches; CDN incidents serving error pages with 200 status.
Related errors
- expected exactly one Hex OTP build record for {release_tag},
- Invalid lockfile checksum for precompiled Erlang/OTP {versio
- precompiled erlang is not available: {reason}
- precompiled erlang is not supported on musl linux
- unsupported architecture: {other}
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/5efd986fe7cd40fa.
Report an issue: GitHub.