wmjordan/PDFPatcher · error · ExifLibException
File is not a valid JPEG
Error message
File is not a valid JPEG
What it means
JpgHelper.Initialize throws ExifLibException('File is not a valid JPEG') when the first two bytes of the stream are not the JPEG SOI marker 0xFFD8. This is the entry-point validation that the supplied stream is actually a JPEG before attempting Exif parsing.
Source
Thrown at App/Processor/Imaging/JpgHelper.cs:142
}
private void Initialize() {
if (_isInitialized)
return;
_isInitialized = true;
// JPEG encoding uses big endian (i.e. Motorola) byte aligns. The TIFF encoding
// found later in the document will specify the byte aligns used for the
// rest of the document.
_isLittleEndian = false;
// Open the file in a stream
_reader = new BinaryReader(_stream, System.Text.Encoding.UTF8);
// Make sure the file's a JPEG.
if (ReadUShort() != 0xFFD8)
throw new ExifLibException("File is not a valid JPEG");
// Scan to the start of the Exif content
ReadToExifStart();
// Create an index of all Exif tags found within the document
CreateTagIndex();
}
#region TIFF methods
/// <summary>
/// Returns the length (in bytes) per component of the specified TIFF data type
/// </summary>
/// <returns></returns>
private static byte GetTIFFFieldLength(ushort tiffDataType) {
return tiffDataType switch {
1 or 2 or 7 or 6 => 1,
3 or 8 => 2,
View on GitHub (pinned to 4782bbd9ad)
Solutions
- Verify the file type (by magic bytes / extension) before handing the stream to ExifReader.
- Ensure the stream position is at 0 before construction.
- For extracted PDF images, check the image filter/mime type to confirm it is DCTDecode (JPEG) before Exif parsing.
- Handle ExifLibException gracefully and skip Exif extraction for non-JPEG formats.
Example fix
// before
var reader = new ExifReader(stream);
// after
if (!IsJpeg(stream)) {
return; // skip Exif for non-JPEG
}
stream.Position = 0;
var reader = new ExifReader(stream);
static bool IsJpeg(Stream s) {
long p = s.Position; s.Position = 0;
int b0 = s.ReadByte(), b1 = s.ReadByte();
s.Position = p;
return b0 == 0xFF && b1 == 0xD8;
} Defensive patterns
Strategy: validation
Validate before calling
long pos = stream.Position; stream.Position = 0; int b0 = stream.ReadByte(), b1 = stream.ReadByte(); stream.Position = pos; if (b0 != 0xFF || b1 != 0xD8) return; // not a JPEG
Type guard
static bool IsJpeg(Stream s) {
long p = s.Position; s.Position = 0;
int b0 = s.ReadByte(), b1 = s.ReadByte(); s.Position = p;
return b0 == 0xFF && b1 == 0xD8;
} Try / catch
try { var r = new ExifReader(stream); }
catch (ExifLibException) { /* not a JPEG; skip Exif */ } Prevention
- Check magic bytes before Exif parsing.
- Reset stream position to 0 before constructing the reader.
- Confirm PDF image filter is DCTDecode before treating as JPEG.
When it happens
Trigger: Constructing the ExifReader (which lazily calls Initialize) with a stream whose first two bytes are not 0xFF 0xD8 — e.g. a PNG, GIF, TIFF, PDF, or truncated/corrupt file passed where a JPEG was expected.
Common situations: Passing a non-JPEG image stream to the Exif reader; a file with the wrong extension; a corrupted or zero-byte JPEG; a stream whose position is not at the start; mistakenly feeding a PDF object stream that isn't a JPEG.
Related errors
- Could not find Exif data block
- Exif data not found
- Malformed Exif data
- Error in TIFF data
- The image you are attempting to quantize does not contain a
AI-assisted analysis of wmjordan/PDFPatcher@4782bbd9ad (2026-08-13).
Data as JSON: /api/errors/672d41e64520f203.
Report an issue: GitHub.