mozilla/pdf.js · error · JpegError
SOI not found
Error message
SOI not found
What it means
Thrown by the static method JpegImage.canUseImageDecoder() when the first two bytes of the supplied data are not 0xFFD8 (the JPEG Start-Of-Image marker). canUseImageDecoder is a pre-check that decides whether the platform's native image decoder can handle the stream; if the data isn't JPEG at all, it bails immediately.
Source
Thrown at src/core/jpg.js:820
}
return endOffset;
}
class JpegImage {
constructor({ decodeTransform = null, colorTransform = -1 } = {}) {
this._decodeTransform = decodeTransform;
this._colorTransform = colorTransform;
}
static canUseImageDecoder(data, colorTransform = -1) {
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
let exifOffsets = null;
let offset = 0;
let numComponents = null;
let fileMarker = view.getUint16(offset);
offset += 2;
if (fileMarker !== /* SOI (Start of Image) = */ 0xffd8) {
throw new JpegError("SOI not found");
}
fileMarker = view.getUint16(offset);
offset += 2;
markerLoop: while (fileMarker !== /* EOI (End of Image) = */ 0xffd9) {
switch (fileMarker) {
case 0xffe1: // APP1 - Exif
// TODO: Remove this once https://github.com/w3c/webcodecs/issues/870
// is fixed.
const { appData, oldOffset, newOffset } = readDataBlock(
data,
view,
offset
);
offset = newOffset;
// 'Exif\x00\x00'
if (View on GitHub (pinned to 5903d58d58)
Solutions
- Verify the stream bytes actually start with 0xFFD8 before calling canUseImageDecoder.
- Check the PDF object's /Filter — if it isn't DCTDecode, route to the correct decoder (JPXDecode, FlateDecode, etc.).
- Ensure stream extraction preserves byte 0 (no leading padding/whitespace accidentally included).
Example fix
// before const canUse = JpegImage.canUseImageDecoder(data); // after const isJpeg = data.length >= 2 && data[0] === 0xff && data[1] === 0xd8; const canUse = isJpeg ? JpegImage.canUseImageDecoder(data) : null;
Defensive patterns
Strategy: validation
Validate before calling
function looksLikeJpeg(data) {
return data && data.length >= 2 && data[0] === 0xff && data[1] === 0xd8;
}
// call before JpegImage.canUseImageDecoder(data) Type guard
function isJpegHeader(data) {
return data instanceof Uint8Array && data.length >= 2 && data[0] === 0xff && data[1] === 0xd8;
} Try / catch
try { JpegImage.canUseImageDecoder(data); }
catch (e) { if (e.name === 'JpegError') { /* not JPEG, route elsewhere */ } else throw e; } Prevention
- Check the first two bytes for 0xFFD8 before invoking the JPEG path.
- Verify the PDF object's /Filter is DCTDecode before treating bytes as JPEG.
- Ensure stream extraction starts at byte 0 (no offset/whitespace prefix).
When it happens
Trigger: Calling JpegImage.canUseImageDecoder(data) where data does not begin with 0xFFD8 — e.g. the bytes are PNG, JBIG2, JPX, or random/corrupt content that was incorrectly tagged as JPEG.
Common situations: A PDF image XObject with /Filter /DCTDecode whose stream is actually another format, or a stream that was truncated before the SOI. Also occurs if the wrong byte slice is passed (offset/length miscalculation when extracting the stream).
Related errors
- Duplicate EXIF-blocks found.
- Only single frame JPEGs supported
- JpegImage.parse - unknown marker: ${fileMarker.toString(16)}
- JpegImage.parse - no frame data found.
- invalid huffman sequence
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/8ae722c6eb5cded8.
Report an issue: GitHub.