QL-Win/QuickLook · error · PEImageParseException
DOS header incomplete.
Error message
DOS header incomplete.
What it means
Thrown when, after the 'MZ' mark, fewer than 64 bytes remain in the stream — insufficient to hold the full IMAGE_DOS_HEADER (which is 64 bytes). PEImageParseException records the current position. The file started as an executable but is too short to contain the DOS header it claims to need.
Source
Thrown at QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/PEImage.cs:55
public ImageOptionalHeader OptionalHeader { get; private set; }
/// <summary>
/// Gets the collection of section headers and data of this PE image file.
/// </summary>
public ImageSection[] Sections { get; private set; }
private PEImage(byte[] originalImage)
{
OriginalImage = originalImage;
using BinaryReader reader = new(new MemoryStream(OriginalImage));
// MZ
if (reader.BaseStream.Length < 2) throw new PEImageParseException(0, "DOS signature not found.");
if (reader.ReadUInt16() != 0x5a4d) throw new PEImageParseException(0, "DOS header not found.");
// DOS Header
if (reader.BaseStream.Length - reader.BaseStream.Position < 64) throw new PEImageParseException((int)reader.BaseStream.Position, "DOS header incomplete.");
DosHeader = new()
{
LastPageSize = reader.ReadUInt16(),
PageCount = reader.ReadUInt16(),
RelocationCount = reader.ReadUInt16(),
HeaderSize = reader.ReadUInt16(),
MinAlloc = reader.ReadUInt16(),
MaxAlloc = reader.ReadUInt16(),
InitialSS = reader.ReadUInt16(),
InitialSP = reader.ReadUInt16(),
Checksum = reader.ReadUInt16(),
InitialIP = reader.ReadUInt16(),
InitialCS = reader.ReadUInt16(),
RelocationOffset = reader.ReadUInt16(),
OverlayNumber = reader.ReadUInt16(),
Reserved1 = reader.ReadUInt16(),
Reserved2 = reader.ReadUInt16(),View on GitHub (pinned to cb5d9c429c)
Solutions
- Pre-check that the file is at least 64 bytes before constructing PEImage.
- If the file is expected to be a real PE, re-acquire it — truncation here means it cannot be valid.
- Catch PEImageParseException and report 'incomplete DOS header / not a valid PE'.
- Validate download integrity (size/hash) before parsing.
Example fix
// before if (reader.BaseStream.Length - reader.BaseStream.Position < 64) throw new PEImageParseException((int)reader.BaseStream.Position, "DOS header incomplete."); // after — single upfront size guard if (reader.BaseStream.Length < 64) return null;
Defensive patterns
Strategy: validation
Validate before calling
if (new FileInfo(path).Length < 64) return; // cannot contain a full DOS header
Type guard
static bool HasFullDosHeader(long len) => len >= 64;
Try / catch
try { var img = PEImage.FromFile(path); }
catch (PEImageParseException ex) when (ex.Message.Contains("DOS header incomplete")) { /* truncated PE */ } Prevention
- Pre-check file length >= 64 before parsing.
- Validate download size/hash before opening.
- Re-acquire truncated executables.
When it happens
Trigger: reader.BaseStream.Length - reader.BaseStream.Position < 64 immediately after consuming the 2-byte 'MZ' magic — e.g. a 3–65 byte file, or a stream truncated just past the magic.
Common situations: A stub/sentinel file that begins with 'MZ' but is incomplete; a PE truncated during copy; a deliberately malformed 'MZ' file used as a marker; an SFX header fragment.
Related errors
- Section '{Header.Name}' incomplete.
- DOS signature not found.
- DOS header not found.
- The stream has fewer bytes available than requested.
- The minidump stream directory is outside the file.
AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13).
Data as JSON: /api/errors/eb98476bac8ded4d.
Report an issue: GitHub.