jdx/mise · error
invalid Hex OTP checksum for
Error message
invalid Hex OTP checksum for {release_tag}: {checksum} What it means
After locating the Hex OTP build record, parse_hex_build_checksum validates that the checksum field is a 64-character lowercase hex sha256. A malformed or absent-format checksum indicates corrupted or unexpected upstream data, so it bails.
Solutions
- Clear the cached Hex builds data and retry so a fresh file is fetched
- Upgrade mise in case the parser needs updating for a new upstream format
- Manually verify the Hex builds file for the release and report upstream corruption
Defensive patterns
Strategy: retry
Validate before calling
# validate checksum line shape before parsing
grep -E "^OTP-26\.2\.5\s+\S+\s+\S+\s+[0-9a-f]{64}$" builds.txt Try / catch
mise install erlang@X || { rm -rf ~/.cache/mise/erlang*; mise install erlang@X; } Prevention
- Clear caches when upstream format changes are announced
- Keep mise updated to track upstream Hex builds format
- Don't mirror/edit Hex builds files locally
When it happens
Trigger: The matched Hex builds line has a checksum field at index 3 that is not 64 lowercase hex chars (truncated line, different record format, corrupted download).
Common situations: Upstream Hex file format changes, partially cached/corrupted checksum files, or custom-mirrored Hex data with altered columns.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- expected exactly one Hex OTP build record for
- Invalid lockfile checksum for precompiled Erlang/OTP
- signed mise release checksum manifest contains an invalid…
- brew-cask: : cask metadata has no sha256
- # : malformed sha256
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5efd986fe7cd40fa.
Report an issue: GitHub.
Appendix: source
Thrown at src/plugins/core/erlang.rs:827
.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 533346cc37)