jdx/mise · error · eyre::Report
unsupported ELF class
Error message
unsupported ELF class
What it means
Thrown by elf_interpreter when the ELF EI_CLASS byte (byte 4) is neither 1 (ELF32) nor 2 (ELF64). The parser only understands 32- and 64-bit ELF program headers; any other class value means the header is corrupt or the file is not a conventional Linux executable, and parsing cannot continue safely.
Source
Thrown at src/system/remote.rs:1381
Some(2) => false,
_ => bail!("unsupported ELF byte order"),
};
let (program_offset, entry_size, entry_count, offset_field, size_field) = match class {
1 => (
read_elf_int(bytes, 28, 4, little_endian)?,
read_elf_int(bytes, 42, 2, little_endian)?,
read_elf_int(bytes, 44, 2, little_endian)?,
4,
16,
),
2 => (
read_elf_int(bytes, 32, 8, little_endian)?,
read_elf_int(bytes, 54, 2, little_endian)?,
read_elf_int(bytes, 56, 2, little_endian)?,
8,
32,
),
_ => bail!("unsupported ELF class"),
};
let program_offset = usize::try_from(program_offset)?;
let entry_size = usize::try_from(entry_size)?;
let entry_count = usize::try_from(entry_count)?;
for index in 0..entry_count {
let start = program_offset
.checked_add(
index
.checked_mul(entry_size)
.ok_or_else(|| eyre!("invalid ELF program headers"))?,
)
.ok_or_else(|| eyre!("invalid ELF program headers"))?;
if read_elf_int(bytes, start, 4, little_endian)? != PT_INTERP {
continue;
}
let offset = usize::try_from(read_elf_int(
bytes,
start + offset_field,View on GitHub (pinned to 6f52dcdf99)
Solutions
- Re-obtain the binary from a trusted source and validate the header (readelf -h mise should show Class: ELF64)
- Strip anything prepended to the file or re-extract the archive properly
- Use remote_mise/bootstrap_command to sidestep local-binary validation
Example fix
# before: binary with damaged header readelf -h ./mise # Class: <invalid> # after: reinstall ./install-mise.sh # or: cargo build --release readelf -h ./target/release/mise # Class: ELF64
Defensive patterns
Strategy: validation
Validate before calling
// Same magic/class guard as 895 covers this arm
fn elf_header_sane(path: &Path) -> bool {
let mut magic = [0u8; 6];
let Ok(mut f) = std::fs::File::open(path) else { return false };
std::io::Read::read_exact(&mut f, &mut magic).is_ok()
&& &magic[..4] == b"\x7fELF"
&& matches!(magic[4], 1 | 2) // ELF32/ELF64 only
&& matches!(magic[5], 1 | 2)
} Type guard
fn elf_header_sane(path: &Path) -> bool {
let mut magic = [0u8; 6];
let Ok(mut f) = std::fs::File::open(path) else { return false };
std::io::Read::read_exact(&mut f, &mut magic).is_ok()
&& &magic[..4] == b"\x7fELF"
&& matches!(magic[4], 1 | 2)
&& matches!(magic[5], 1 | 2)
} Try / catch
match elf_interpreter(&bytes) {
Err(e) if e.to_string().contains("unsupported ELF class") => {
eyre::bail!("mise binary at {} is not a valid ELF32/ELF64 image; rebuild it", path.display());
}
other => other?,
} Prevention
- Do not feed packed/prepended binaries into mise_bin; extract the raw ELF first
- Add readelf/file checks to artifact pipelines so corrupt builds never ship
- Fuzz-corpus or test binaries should not be reused as deploy artifacts
When it happens
Trigger: A truncated or corrupted mise_bin whose class byte is garbage; a crafted/fuzzed binary fed into Linux-to-Linux upload validation.
Common situations: Damaged artifacts from partial copies; test/fuzz corpora accidentally pointed at by mise_bin; files with prepended data (some packers) that shift the header.
Related errors
- unsupported ELF byte order
- local mise is not an ELF executable
- trimPrefix requires exactly 2 arguments
- trimSuffix requires exactly 2 arguments
- action prediction payload is too large
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/e8758a9bddf2af13.
Report an issue: GitHub.