nodejs/node · error · ELFInvalid

unrecognized capacity ({self.capacity}) or encoding ({self.e

Error message

unrecognized capacity ({self.capacity}) or encoding ({self.encoding})

What it means

Raised by ELFFile.__init__ when the capacity (EI_CLASS, byte index 4: 1=32-bit, 2=64-bit) and encoding (EI_DATA, byte index 5: 1=LSB/little-endian, 2=MSB/big-endian) pair is not one of the four supported combinations: (1,1), (1,2), (2,1), (2,2). A KeyError on the lookup dict is caught and re-raised as ELFInvalid with the unrecognized values.

Source

Thrown at tools/gyp/pylib/packaging/_elffile.py:68

            raise ELFInvalid("unable to parse identification")
        if (magic := bytes(ident[:4])) != b"\x7fELF":
            raise ELFInvalid(f"invalid magic: {magic!r}")

        self.capacity = ident[4]  # Format for program header (bitness).
        self.encoding = ident[5]  # Data structure encoding (endianness).

        try:
            # e_fmt: Format for program header.
            # p_fmt: Format for section header.
            # p_idx: Indexes to find p_type, p_offset, and p_filesz.
            e_fmt, self._p_fmt, self._p_idx = {
                (1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)),  # 32-bit LSB.
                (1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)),  # 32-bit MSB.
                (2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)),  # 64-bit LSB.
                (2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)),  # 64-bit MSB.
            }[(self.capacity, self.encoding)]
        except KeyError:
            raise ELFInvalid(
                f"unrecognized capacity ({self.capacity}) or "
                f"encoding ({self.encoding})"
            )

        try:
            (
                _,
                self.machine,  # Architecture type.
                _,
                _,
                self._e_phoff,  # Offset of program header.
                _,
                self.flags,  # Processor-specific flags.
                _,
                self._e_phentsize,  # Size of section.
                self._e_phnum,  # Number of sections.
            ) = self._read(e_fmt)
        except struct.error as e:

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Validate the ELF file is well-formed using readelf or objdump before parsing.
  2. Catch ELFInvalid and report the file as unsupported rather than crashing.
  3. If processing untrusted binaries, wrap ELFFile construction in a try/except and skip unsupported files.
  4. Regenerate or re-fetch the binary if it should be a standard 32/64-bit ELF.

Example fix

try:
    elf = ELFFile(open(path, 'rb'))
except ELFInvalid as e:
    print(f'skipping {path}: {e}')
    continue
Defensive patterns

Strategy: try-catch

Validate before calling

# Check EI_CLASS and EI_DATA are valid before constructing ELFFile
with open(path, 'rb') as f:
    ident = f.read(16)
if ident[:4] != b'\x7fELF' or ident[4] not in (1, 2) or ident[5] not in (1, 2):
    raise ValueError('unsupported ELF class/encoding')

Type guard

def is_supported_elf(path: str) -> bool:
    with open(path, 'rb') as f:
        ident = f.read(16)
    return (
        len(ident) >= 6
        and ident[:4] == b'\x7fELF'
        and ident[4] in (1, 2)
        and ident[5] in (1, 2)
    )

Try / catch

from packaging._elffile import ELFFile, ELFInvalid
try:
    elf = ELFFile(open(path, 'rb'))
except ELFInvalid as e:
    print(f'unsupported ELF: {e}')
    elf = None

Prevention

When it happens

Trigger: The ELF identification bytes 4 and 5 contain values outside {1,2}, or the magic is valid but EI_CLASS/EI_DATA are set to 0, 3, or any reserved/invalid value. This is rare for legitimate ELF files.

Common situations: A deliberately corrupted or fuzzed ELF file. A file that starts with the ELF magic but is not a real ELF (e.g., a test fixture or anti-analysis artifact). Future ELF class/encoding values not yet handled by this parser.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/ae5ebfaf5ac71264. Report an issue: GitHub.