oven-sh/bun · error · ElfError
InvalidElfFile
InvalidElfFile
Error message
InvalidElfFile
What it means
ElfError::InvalidElfFile comes from Bun's own ELF writer (src/exe_format/elf.rs) used by `bun build --compile` (via StandaloneModuleGraph) when appending the embedded module graph to a Linux executable. It fires when the input binary is shorter than an ELF64 header, lacks the \x7fELF magic, or has section-header/shstrtab/RW-segment offsets beyond end-of-file — i.e. the file is not a valid ELF64 or is truncated/corrupted.
Source
Thrown at src/exe_format/elf.rs:23
//! and expands it to hold the standalone module graph data.
//!
//! Must work on any host platform (macOS, Windows, Linux) for cross-compilation.
use core::mem::size_of;
#[cfg(any(target_os = "linux", target_os = "android"))]
use core::sync::atomic::{AtomicU8, Ordering};
#[cfg(any(target_os = "linux", target_os = "android"))]
use bun_core::env_var;
use bun_core::{slice_to_nul, strings};
use crate::{align_up, read_struct, write_struct};
bun_core::declare_scope!(elf, visible);
#[derive(Debug, thiserror::Error, strum::IntoStaticStr)]
pub enum ElfError {
#[error("InvalidElfFile")]
InvalidElfFile,
#[error("Not64Bit")]
Not64Bit,
#[error("NotLittleEndian")]
NotLittleEndian,
#[error("BunSectionNotFound")]
BunSectionNotFound,
#[error("NoWritableLoadSegment")]
NoWritableLoadSegment,
#[error("NewVaddrCollides")]
NewVaddrCollides,
}
pub struct ElfFile {
pub data: Vec<u8>,
}
impl ElfFile {View on GitHub (pinned to 8c5296ac45)
Solutions
- Verify the base binary with `file ./bun` (must say ELF 64-bit LSB) and rebuild/redownload it if truncated.
- Make sure the --compile target triple matches the binary's actual format (use a linux target for ELF patching).
- Re-run the failing build after removing corrupted artifacts; check dmesg/disk if truncation repeats.
Example fix
# before: host binary is not the ELF being patched bun build --compile --target=darwin-arm64 ./app.ts # then patching path given an ELF # after: match formats file ./build/debug/bun-debug # expect: ELF 64-bit LSB ... bun build --compile --target=linux-arm64 ./app.ts
Defensive patterns
Strategy: try-catch
Validate before calling
fn is_elf64_le(data: &[u8]) -> bool {
data.len() >= size_of::<Elf64_Ehdr>() && &data[0..4] == b"\x7fELF"
}
// before patching:
if !is_elf64_le(&template_bytes) {
return Err(format!("template is not ELF64: {}", template_path.display()));
} Type guard
fn is_elf64_le(data: &[u8]) -> bool {
data.len() >= 64 && data[..4] == *b"\x7fELF" && data[4] == 2 /* ELFCLASS64 */ && data[5] == 1 /* ELFDATA2LSB */
} Try / catch
match bun_elf::Elf64::from_bytes(template) {
Ok(mut elf) => elf.add_section(payload)?,
Err(ElfError::InvalidElfFile) => {
return Err(format!("not a valid ELF64 binary (truncated or wrong format): {}", path.display()));
}
Err(ElfError::Not64Bit | ElfError::NotLittleEndian) => return Err("wrong ELF class or endianness".into()),
Err(e) => return Err(e.into()),
} Prevention
- Validate the \x7fELF magic and header size before handing a binary to the ELF patcher.
- Match --compile --target to the real architecture of the base executable; never feed Mach-O/PE files to the ELF path.
- Treat truncated base binaries (interrupted downloads, disk-full builds) as poisoned — rebuild rather than retry.
When it happens
Trigger: Compiling a standalone executable where the ELF template is a Mach-O/PE binary (wrong --target for the host file), a partially copied/truncated bun binary, or a corrupted build artifact with out-of-bounds e_shoff/shstrtab offsets.
Common situations: Cross-compiling with a mismatched --target triple; a base executable corrupted in transfer or by post-processing tools (upx, signers, buggy strip); disk-full during a previous build leaving a truncated binary.
Related errors
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/35307a45431911fb.
Report an issue: GitHub.