parallax/jsPDF · error · Error

Invalid GIF 87a/89a header.

Error message

Invalid GIF 87a/89a header.

What it means

Thrown by the GifReader constructor when the first six bytes do not match the ASCII header 'GIF87a' or 'GIF89a'. The check decodes bytes and verifies the 'GIF8' prefix plus a 7/9 (via (b+1)&0xfd === 0x38) and trailing 'a'. Any non-GIF or truncated buffer fails here.

Source

Thrown at src/libs/omggif.js:432

    buf[cur_subblock] = p - cur_subblock - 1;
    buf[p++] = 0;
  }
  return p;
}

function GifReader(buf) {
  var p = 0;

  // - Header (GIF87a or GIF89a).
  if (
    buf[p++] !== 0x47 ||
    buf[p++] !== 0x49 ||
    buf[p++] !== 0x46 ||
    buf[p++] !== 0x38 ||
    ((buf[p++] + 1) & 0xfd) !== 0x38 ||
    buf[p++] !== 0x61
  ) {
    throw new Error("Invalid GIF 87a/89a header.");
  }

  // - Logical Screen Descriptor.
  var width = buf[p++] | (buf[p++] << 8);
  var height = buf[p++] | (buf[p++] << 8);
  var pf0 = buf[p++]; // <Packed Fields>.
  var global_palette_flag = pf0 >> 7;
  var num_global_colors_pow2 = pf0 & 0x7;
  var num_global_colors = 1 << (num_global_colors_pow2 + 1);
  var background = buf[p++];
  buf[p++]; // Pixel aspect ratio (unused?).

  var global_palette_offset = null;
  var global_palette_size = null;

  if (global_palette_flag) {
    global_palette_offset = p;
    global_palette_size = num_global_colors;

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Sniff the magic bytes (0x47 0x49 0x46 'GIF') before constructing GifReader.
  2. Route by actual format (use the matching decoder for PNG/JPEG/etc.).
  3. Ensure you pass a complete Uint8Array/ArrayBuffer, not a base64 string.

Example fix

// before
var reader = new GifReader(buffer);
// after
if (buffer.length >= 6 && buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {
  var reader = new GifReader(buffer);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function isGif(buf){ return buf && buf.length >= 6 && buf[0]===0x47 && buf[1]===0x49 && buf[2]===0x46 && buf[3]===0x38; }
if (isGif(buffer)) new GifReader(buffer);

Type guard

function isGifBuffer(buf){ return buf instanceof Uint8Array && buf.length >= 6 && buf[0]===0x47 && buf[1]===0x49 && buf[2]===0x46; }

Try / catch

try { var r = new GifReader(buffer); } catch (e) { if (/Invalid GIF/.test(e.message)) { /* route to correct decoder */ } else throw e; }

Prevention

When it happens

Trigger: Passing a PNG/JPEG/WebP/BMP buffer to GifReader; passing a buffer shorter than 6 bytes; corrupted/truncated download; base64 string instead of bytes.

Common situations: Generic image pipeline misrouting non-GIF data to the GIF decoder; serving a file with the wrong MIME/extension; incomplete fetch returning partial bytes.

Related errors


AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13). Data as JSON: /api/errors/6795d8c181e80a15. Report an issue: GitHub.