{"record":{"id":"ddf9f43f01ceb9c3","repo":"mozilla/pdf.js","slug":"unexpected-marker-bitsdata-8-nextbyte-t","errorCode":null,"errorMessage":"unexpected marker ${((bitsData << 8) | nextByte).toString(16)}","messagePattern":"unexpected marker (.+?)","errorType":"exception","errorClass":"JpegError","httpStatus":null,"severity":"error","filePath":"src/core/jpg.js","lineNumber":186,"sourceCode":"            // parsed number of scanLines when it's at least (approximately)\n            // one \"half\" order of magnitude smaller than expected (fixes\n            // issue10880.pdf, issue10989.pdf, issue15492.pdf).\n            if (\n              maybeScanLines > 0 &&\n              Math.round(frame.scanLines / maybeScanLines) >= 5\n            ) {\n              throw new DNLMarkerError(\n                \"Found EOI marker (0xFFD9) while parsing scan data, \" +\n                  \"possibly caused by incorrect `scanLines` parameter\",\n                maybeScanLines\n              );\n            }\n          }\n          throw new EOIMarkerError(\n            \"Found EOI marker (0xFFD9) while parsing scan data\"\n          );\n        }\n        throw new JpegError(\n          `unexpected marker ${((bitsData << 8) | nextByte).toString(16)}`\n        );\n      }\n      // unstuff 0\n    }\n    bitsCount = 7;\n    return bitsData >>> 7;\n  }\n\n  function decodeHuffman(tree) {\n    let node = tree;\n    while (true) {\n      node = node[readBit()];\n      switch (typeof node) {\n        case \"number\":\n          return node;\n        case \"object\":\n          continue;","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/jpg.js#L168-L204","documentation":"Thrown as JpegError when readBit encounters a non-zero byte after 0xFF that is neither DNL (0xDC) nor EOI (0xD9) — i.e. an unexpected JPEG marker embedded inside the scan data. The scan bit-stream should only ever byte-stuff 0xFF00; any other marker is invalid mid-scan.","triggerScenarios":"Decoding a JPEG whose scan data contains a stray marker (e.g. 0xFFC0-style restart/SOF marker) at a position where a stuffed byte or entropy data was expected. Reached during DCTDecode image rendering of a corrupt or non-conformant JPEG.","commonSituations":"Truncated/concatenated JPEGs, restart markers in the wrong place, JPEGs damaged by a copy/merge, or streams produced by encoders that emit non-standard markers mid-scan.","solutions":["Re-encode the source JPEG with a standard encoder to eliminate stray markers.","Validate the JPEG with jpegtran/djpeg before embedding to catch structural errors.","Catch JpegError at render time and substitute a placeholder image.","Regenerate the PDF with a known-good image and re-render."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// No general pre-check; you can scan for stray markers mid-scan, but it is\n// expensive. As a sanity gate, confirm the stream starts with SOI (0xFFD8):\nfunction jpegHasSoi(bytes) {\n  return bytes instanceof Uint8Array && bytes.length >= 2 &&\n    bytes[0] === 0xff && bytes[1] === 0xd8;\n}","typeGuard":"function isJpegError(err) {\n  return err?.name === 'JpegError' && /unexpected marker/.test(err?.message || '');\n}","tryCatchPattern":"try { await page.render({ canvasContext }).promise; }\ncatch (err) {\n  if (err?.name === 'JpegError' && /unexpected marker/.test(err.message)) {\n    console.warn('Corrupt JPEG marker; substituting placeholder image.');\n  } else throw err;\n}","preventionTips":["Re-encode JPEGs with a standard encoder (libjpeg/mozjpeg) before embedding.","Validate with jpegtran -copy none to detect structural issues.","Catch JpegError at render time and substitute a fallback image."],"tags":["pdf","jpeg","dctdecode","marker","corrupt"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}