t8y2/dbx · error · PeFormatError

unexpected end of PE file

Error message

unexpected end of PE file

What it means

The Windows PE dependency validator parses PE binary structures with bounded reads. _read_u16 raises PeFormatError('unexpected end of PE file') when a 2-byte read at the given offset would run past the end of the loaded data (or offset is negative), meaning the file is truncated or not a valid PE image.

Source

Thrown at agents/scripts/validate_windows_pe_dependencies.py:14

#!/usr/bin/env python3

import argparse
import struct
from pathlib import Path


class PeFormatError(ValueError):
    pass


def _read_u16(data: bytes, offset: int) -> int:
    if offset < 0 or offset + 2 > len(data):
        raise PeFormatError("unexpected end of PE file")
    return struct.unpack_from("<H", data, offset)[0]


def _read_u32(data: bytes, offset: int) -> int:
    if offset < 0 or offset + 4 > len(data):
        raise PeFormatError("unexpected end of PE file")
    return struct.unpack_from("<I", data, offset)[0]


def _read_c_string(data: bytes, offset: int) -> str:
    if offset < 0 or offset >= len(data):
        raise PeFormatError("PE string offset is outside the file")
    end = data.find(b"\0", offset)
    if end < 0:
        raise PeFormatError("unterminated PE string")
    try:
        return data[offset:end].decode("ascii")
    except UnicodeDecodeError as error:

View on GitHub (pinned to c0390bff16)

Solutions

  1. Re-download or rebuild the PE file — it is truncated or corrupted.
  2. Verify the file is a real Windows PE (starts with 'MZ', reasonable size) before validating.
  3. Check file size against the expected artifact size/checksum from the release manifest.
  4. Ensure the validator is pointed at a Windows binary, not an ELF/Mach-O or archive.

Example fix

# before
validate_windows_pe_dependencies.py path/to/partial-download.dll
# after
verify checksum of the artifact, re-download, then validate_windows_pe_dependencies.py path/to/file.dll
Defensive patterns

Strategy: validation

Validate before calling

def looks_like_pe(path, min_size=64):
    data = path.read_bytes()
    return len(data) >= min_size and data[:2] == b"MZ"

if not looks_like_pe(Path(dll_path)):
    raise SystemExit(f"{dll_path} is not a valid PE file")

Type guard

def is_pe(data: bytes) -> bool:
    return len(data) >= 64 and data[:2] == b"MZ"

Try / catch

try:
    dlls = imported_dlls(path)
except PeFormatError as e:
    print(f"skipping {path}: {e}")

Prevention

When it happens

Trigger: imported_dlls calls _read_u16 with an offset within 2 bytes of the buffer end — typically because the file being validated is truncated, still downloading, or is not actually a PE (EXE/DLL) file so structure offsets are meaningless.

Common situations: Validating a partially downloaded installer; pointing the validator at a text file, ZIP, or Mach-O/ELF binary by mistake; virus scanner or transfer tool truncated the DLL; corrupt artifact from a broken CI upload.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/641b5839a57cf63e. Report an issue: GitHub.