mozilla/pdf.js · error · Error

Bad begin offset: ${begin}

Error message

Bad begin offset: ${begin}

What it means

Thrown by ChunkedStream.onReceiveData when the incoming data's `begin` offset is not an exact multiple of the stream's chunkSize. ChunkedStream partitions a PDF into fixed-size chunks and requires all received ranges to be chunk-aligned so it can mark the correct _loadedChunks entries.

Source

Thrown at src/core/chunked_stream.js:64

      if (!this._loadedChunks.has(chunk)) {
        chunks.push(chunk);
      }
    }
    return chunks;
  }

  get numChunksLoaded() {
    return this._loadedChunks.size;
  }

  get isDataLoaded() {
    return this.numChunksLoaded === this.numChunks;
  }

  onReceiveData(begin, chunk) {
    const chunkSize = this.chunkSize;
    if (begin % chunkSize !== 0) {
      throw new Error(`Bad begin offset: ${begin}`);
    }

    // Using `this.length` is inaccurate here since `this.start` can be moved
    // (see the `moveStart` method).
    const end = begin + chunk.byteLength;
    if (end % chunkSize !== 0 && end !== this.bytes.length) {
      throw new Error(`Bad end offset: ${end}`);
    }

    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
      assert(
        chunk instanceof ArrayBuffer,
        "onReceiveData - expected an ArrayBuffer."
      );
    }
    this.bytes.set(new Uint8Array(chunk), begin);
    const beginChunk = Math.floor(begin / chunkSize);
    const endChunk = Math.floor((end - 1) / chunkSize) + 1;

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Ensure the server honors Range requests and returns bodies aligned to the client's rangeChunkSize (default 65536).
  2. Verify rangeChunkSize passed to getDocument matches what your transport actually delivers.
  3. If you cannot control alignment, disable range/streamed loading (set disableRange: true, disableStream: true) so the full file is fetched.
  4. Inspect the transport layer (PDFDataRangeTransport or fetch_stream) for incorrect begin values being passed to onReceiveData.

Example fix

// before
const loadingTask = pdfjsLib.getDocument({ url, rangeChunkSize: 65536 });
// server returns misaligned ranges -> throw

// after (option A: disable range loading)
const loadingTask = pdfjsLib.getDocument({
  url,
  disableRange: true,
  disableStream: true,
});

// after (option B: align server Range responses to rangeChunkSize)
// ensure the origin returns Content-Range whose start is a multiple of 65536
Defensive patterns

Strategy: validation

Validate before calling

// Validate chunk alignment before forwarding to onReceiveData.
function validateChunkAlignment(stream, begin, chunk) {
  if (begin % stream.chunkSize !== 0) {
    throw new Error(`Misaligned chunk: begin=${begin} chunkSize=${stream.chunkSize}`);
  }
  const end = begin + chunk.byteLength;
  if (end % stream.chunkSize !== 0 && end !== stream.bytes.length) {
    throw new Error(`Misaligned chunk end: end=${end}`);
  }
}

Type guard

function isChunkAligned(begin, chunkSize) {
  return Number.isInteger(begin) && begin >= 0 && begin % chunkSize === 0;
}

Try / catch

try {
  stream.onReceiveData(begin, chunk);
} catch (e) {
  // Transport delivered misaligned data; fall back to full-file fetch.
  console.warn('Chunked stream alignment error; disabling range loading:', e);
  // Re-load with disableRange: true
}

Prevention

When it happens

Trigger: A range-request server or custom PDFDataTransportStream returns data at a byte offset that is not a multiple of chunkSize (e.g., chunkSize 65536 but data arrives at offset 1000). onReceiveData is called by the transport when chunked/range streaming is enabled.

Common situations: A CDN or reverse proxy that re-chunks responses or strips Content-Range alignment; a custom Range header implementation computing offsets incorrectly; mismatched chunkSize between server and client; HTTP/2 framing that splits the body at non-chunk boundaries; a misconfigured PDFJS.disableRange or rangeChunkSize option.

Related errors


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/b886a81c2fe1bb4e. Report an issue: GitHub.