QL-Win/QuickLook · error · PEImageParseException
Optional header incomplete.
Error message
Optional header incomplete.
What it means
When the optional header magic is 0x10b (PE32, 32-bit image), the fixed portion of the optional header is 96 bytes total — 2 bytes of magic plus 94 bytes of fields. The parser checks that at least 94 bytes remain after the magic; if fewer remain, the PE32 optional header is incomplete and fields such as ImageBase, SectionAlignment, SizeOfImage, and NumberOfRvaAndSizes cannot be safely read. The exception Offset is the position right after the magic.
Source
Thrown at QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/PEImage.cs:117
CoffHeader = new()
{
Machine = (ImageMachineType)reader.ReadUInt16(),
NumberOfSections = reader.ReadUInt16(),
TimeDateStamp = reader.ReadUInt32(),
PointerToSymbolTable = reader.ReadUInt32(),
NumberOfSymbols = reader.ReadUInt32(),
SizeOfOptionalHeader = reader.ReadUInt16(),
Characteristics = (ImageCharacteristics)reader.ReadUInt16()
};
// Optional Header
if (reader.BaseStream.Length - reader.BaseStream.Position < 2) throw new PEImageParseException((int)reader.BaseStream.Position, "Optional header not found.");
ushort magic = reader.ReadUInt16();
if (magic == 0x10b)
{
if (reader.BaseStream.Length - reader.BaseStream.Position < 94) throw new PEImageParseException((int)reader.BaseStream.Position, "Optional header incomplete.");
OptionalHeader = new ImageOptionalHeader32
{
MajorLinkerVersion = reader.ReadByte(),
MinorLinkerVersion = reader.ReadByte(),
SizeOfCode = reader.ReadUInt32(),
SizeOfInitializedData = reader.ReadUInt32(),
SizeOfUninitializedData = reader.ReadUInt32(),
AddressOfEntryPoint = reader.ReadUInt32(),
BaseOfCode = reader.ReadUInt32(),
BaseOfData = reader.ReadUInt32(),
ImageBase = reader.ReadUInt32(),
SectionAlignment = reader.ReadUInt32(),
FileAlignment = reader.ReadUInt32(),
MajorOperatingSystemVersion = reader.ReadUInt16(),
MinorOperatingSystemVersion = reader.ReadUInt16(),
MajorImageVersion = reader.ReadUInt16(),
MinorImageVersion = reader.ReadUInt16(),View on GitHub (pinned to cb5d9c429c)
Solutions
- Re-acquire the 32-bit binary from its source and verify the file size and hash match the original
- Pre-check that the file length is at least PEHeaderOffset + 4 (signature) + 20 (COFF) + 96 (PE32 optional header) before parsing
- Catch PEImageParseException and treat the file as corrupt rather than crashing
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify enough bytes for PE32 optional header (96 bytes total)
static bool IsLargeEnoughForPE32Optional(string path)
{
byte[] b = File.ReadAllBytes(path);
if (b.Length < 0x40) return false;
int peOff = BitConverter.ToInt32(b, 0x3C);
int optStart = peOff + 4 + 20; // after PE sig + COFF header
return b.Length >= optStart + 96; // 2 magic + 94 fields
} Try / catch
try
{
var image = PEImage.FromFile(path);
}
catch (PEImageParseException ex) when (ex.Message == "Optional header incomplete.")
{
// File truncated mid-optional-header (PE32 or PE32+)
logger.Warn($"Truncated optional header at offset {ex.Offset}");
} Prevention
- Verify file integrity via hash before parsing 32-bit PE images
- Pre-check file size is at least PEHeaderOffset + 120 bytes (sig + COFF + PE32 optional header)
- Treat PEImageParseException as a signal of a corrupt or incomplete file
When it happens
Trigger: The optional header magic was read as 0x10b but the stream has fewer than 94 bytes left. The file is a 32-bit PE that is truncated in the middle of its optional header, after the magic but before all 94 remaining fields are present.
Common situations: A 32-bit .exe or .dll truncated during download or transfer, cut off within the optional header region; a malformed or crafted binary with a valid PE32 magic but an incomplete optional header body.
Related errors
- COFF header incomplete.
- Optional header not found.
- Data directories incomplete.
- Section headers incomplete.
- COFF header not found.
AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13).
Data as JSON: /api/errors/ae8d6b96dda01053.
Report an issue: GitHub.