pypa/pip · 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, encoding)` pair from `e_ident` bytes 4 and 5 is not one of the four supported combinations (32/64-bit × LSB/MSB). The capacity field is the bitness (1=32, 2=64) and the encoding field is endianness (1=LSB/little, 2=MSB/big). Any other value means the file is corrupted or uses an exotic/unsupported ELF variant.

Source

Thrown at src/pip/_vendor/packaging/_elffile.py:70

        magic = bytes(ident[:4])
        if magic != 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 as e:
            raise ELFInvalid(
                f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})"
            ) from e

        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:
            raise ELFInvalid("unable to parse machine and section information") from e

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Re-fetch or rebuild the binary — corrupted ELF headers are not recoverable
  2. Validate bytes 4-5 fall in {(1,1),(1,2),(2,1),(2,2)} before constructing ELFFile
  3. If scanning many files, treat ELFInvalid as 'skip this file'

Example fix

// before
elf = ELFFile(f)
// after
f.seek(4)
ce, en = struct.unpack('BB', f.read(2))
if (ce, en) not in {(1,1),(1,2),(2,1),(2,2)}:
    raise ValueError(f'unsupported ELF class/endianness {(ce,en)}')
f.seek(0)
elf = ELFFile(f)
Defensive patterns

Strategy: try-catch

Validate before calling

import struct
SUPPORTED = {(1,1),(1,2),(2,1),(2,2)}

def elf_class_encoding(path: str):
    with open(path,'rb') as f:
        f.seek(4)
        ce, en = struct.unpack('BB', f.read(2))
    if (ce,en) not in SUPPORTED:
        raise ValueError(f'unsupported ELF class/endianness {(ce,en)}')
    return ce, en

Type guard

def is_supported_elf_variant(ce: int, en: int) -> bool:
    return (ce, en) in {(1,1),(1,2),(2,1),(2,2)}

Try / catch

from packaging._elffile import ELFFile, ELFInvalid
try:
    elf = ELFFile(f)
except ELFInvalid as e:
    if 'unrecognized capacity' in str(e):
        log.warning('exotic ELF variant in %s, skipping', path)
        continue
    raise

Prevention

When it happens

Trigger: Parsing a corrupted ELF whose header bytes 4-5 were clobbered; a fuzzed test artifact; a real ELF on an unusual architecture where the OS/ABI byte was misinterpreted. The supported set is intentionally minimal (the four mainstream combinations).

Common situations: A truncated/partially-written `.so` from a crashed compiler; byte-flip during download; test fixtures generated by truncating real binaries; rare big-endian embedded targets that use a non-1/2 encoding byte.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/d2de542036956761.json. Report an issue: GitHub.