QL-Win/QuickLook · error · PEImageParseException
Optional header not found.
Error message
Optional header not found.
What it means
Immediately after the 20-byte COFF header, the optional header begins with a 2-byte magic number that identifies the image subtype (PE32, PE32+, or ROM). The parser requires at least 2 bytes remaining to read this magic; if fewer bytes remain the optional header does not exist and parsing aborts. The exception Offset marks where the magic should have been.
Source
Thrown at QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/PEImage.cs:112
DosStub = reader.ReadBytes((int)(DosHeader.PEHeaderOffset - reader.BaseStream.Position));
// COFF Header
if (reader.ReadUInt32() != 0x4550) throw new PEImageParseException((int)reader.BaseStream.Position - 4, "COFF header not found.");
if (reader.BaseStream.Length - reader.BaseStream.Position < 20) throw new PEImageParseException((int)reader.BaseStream.Position, "COFF header incomplete.");
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(),View on GitHub (pinned to cb5d9c429c)
Solutions
- Confirm you are passing a linked PE image (.exe or .dll), not a COFF object file (.obj)
- If the file is an image, re-download and verify its integrity via hash comparison
- Guard the call with try-catch(PEImageParseException) when processing untrusted or user-selected files
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify SizeOfOptionalHeader > 0 (object files have it set to 0)
static bool HasOptionalHeader(string path)
{
byte[] b = File.ReadAllBytes(path);
if (b.Length < 0x40) return false;
int peOff = BitConverter.ToInt32(b, 0x3C);
int coffOff = peOff + 4; // after PE signature
if (coffOff + 20 > b.Length) return false;
// SizeOfOptionalHeader is at COFF offset + 16 (2 bytes)
ushort sizeOfOptHeader = BitConverter.ToUInt16(b, coffOff + 16);
return sizeOfOptHeader > 0;
} Try / catch
try
{
var image = PEImage.FromFile(path);
}
catch (PEImageParseException ex) when (ex.Message.Contains("Optional header not found"))
{
// Likely a .obj object file or truncated image
logger.Warn($"No optional header: {ex.Message}");
} Prevention
- Do not pass COFF object files (.obj) to this parser — it expects linked PE images only
- Check that the file extension and content indicate an image (.exe/.dll), not an object or archive
- Verify file completeness before parsing untrusted binaries
When it happens
Trigger: The COFF header was parsed successfully but fewer than 2 bytes remain in the stream. This occurs when the file ends immediately after the COFF header, or when the COFF header's SizeOfOptionalHeader field is 0 (typical of COFF object files that are not memory images).
Common situations: Passing a COFF object file (.obj) instead of a linked image (.exe/.dll) — object files have SizeOfOptionalHeader = 0 and no optional header; a truncated download where the file ends at the COFF/optional-header boundary; a stripped or malformed image.
Related errors
- COFF header incomplete.
- Optional header incomplete.
- 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/715f8920dfdb7bf7.
Report an issue: GitHub.