jdx/mise · error
unexpected ELF e_phentsize
Error message
unexpected ELF e_phentsize {e_phentsize} What it means
The ELF patcher parses the program header table using the standard 64-bit ELF entry size (PHDR_SIZE, 56 bytes) only. If e_phentsize in the ELF header differs, the parser cannot safely index the table, so read_phdrs bails instead of reading garbage. This protects patch/read_linkage from corrupting binaries laid out with non-standard program header entries.
Solutions
- Verify the binary is a normal 64-bit LE ELF (readelf -l) and rebuild it with the standard toolchain if e_phentsize is non-standard.
- Re-download or re-extract the bottle/binary — the file may be corrupted.
- Handle the error: the patcher intentionally refuses such files; skip or fall back to an external tool like patchelf for them.
Defensive patterns
Strategy: try-catch
Validate before calling
// check before patching
let e_phentsize = u16::from_le_bytes([content[54], content[55]]);
if e_phentsize != 56 { /* skip or use fallback tool */ } Type guard
fn has_standard_phdr_entry_size(elf: &[u8]) -> bool {
elf.len() > 56 && u16::from_le_bytes([elf[54], elf[55]]) == 56
} Try / catch
match elf::patch(&mut content, &opts, &path) {
Err(e) if e.to_string().contains("e_phentsize") => {
warn!("{}: non-standard ELF layout, skipping", path.display());
}
other => other?,
} Prevention
- Only process binaries built by the standard 64-bit toolchain.
- Validate bottle integrity (checksums) before relocation.
- Treat the ELF patcher as best-effort: skip unsupported files rather than force-patching.
When it happens
Trigger: Calling elf::patch, read_linkage, or the test helpers on an ELF whose e_phentsize is not 56 — e.g. a 32-bit ELF (though those are skipped earlier), an unusual linker's output, or a corrupted/truncated file whose header bytes were misread.
Common situations: Bottling or relinking a binary produced by an exotic toolchain or packer; processing a corrupted or deliberately malformed ELF; feeding a stripped/rewritten binary that altered header fields.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- cannot relocate : rpath must grow but the dynamic string…
- brew-cask: : only font-only casks without lifecycle hooks…
- ELF uses PN_XNUM program header counts
- local mise is not an ELF executable
- no dynamic linker found for
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/e28cad677a9768c8.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/brew/elf.rs:114
b[off..off + 8].copy_from_slice(&v.to_le_bytes());
}
#[derive(Clone, Copy)]
struct Phdr {
p_type: u32,
p_offset: u64,
p_vaddr: u64,
p_filesz: u64,
p_memsz: u64,
p_align: u64,
}
fn read_phdrs(content: &[u8]) -> Result<Vec<Phdr>> {
let e_phoff = rd_u64(content, 32)? as usize;
let e_phentsize = rd_u16(content, 54)? as usize;
let e_phnum = rd_u16(content, 56)? as usize;
if e_phentsize != PHDR_SIZE {
bail!("unexpected ELF e_phentsize {e_phentsize}");
}
if e_phnum >= 0xffff {
bail!("ELF uses PN_XNUM program header counts");
}
let mut phdrs = Vec::with_capacity(e_phnum);
for i in 0..e_phnum {
let off = e_phoff + i * PHDR_SIZE;
phdrs.push(Phdr {
p_type: rd_u32(content, off)?,
p_offset: rd_u64(content, off + 8)?,
p_vaddr: rd_u64(content, off + 16)?,
p_filesz: rd_u64(content, off + 32)?,
p_memsz: rd_u64(content, off + 40)?,
p_align: rd_u64(content, off + 48)?,
});
}
Ok(phdrs)
}View on GitHub (pinned to 533346cc37)