BabylonJS/Babylon.js · error

deflate: invalid stored block length

Error message

deflate: invalid stored block length

What it means

A stored (uncompressed, type-0) deflate block stores LEN and NLEN where NLEN must be the bitwise complement of LEN. This error is thrown when the one's-complement check fails, so the bytes being read as a stored-block header are not a valid stored block — typically the reader is not where it thinks it is, or the data is not deflate at all.

Source

Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:303

        }
        fixedLiteralLengthTree = new HuffmanTree(lengths);
    }
    return fixedLiteralLengthTree;
}

function getFixedDistanceTree(): HuffmanTree {
    if (!fixedDistanceTree) {
        fixedDistanceTree = new HuffmanTree(new Array<number>(32).fill(5));
    }
    return fixedDistanceTree;
}

function inflateStoredBlock(reader: BitReader, output: OutputWriter): void {
    reader.alignToByte();
    const length = reader.readUint16LE();
    const inverseLength = reader.readUint16LE();
    if (((length ^ inverseLength) & 0xffff) !== 0xffff) {
        throw new Error("deflate: invalid stored block length");
    }

    for (let i = 0; i < length; i++) {
        output.writeByte(reader.readByte());
    }
}

function inflateCompressedBlock(reader: BitReader, output: OutputWriter, literalLengthTree: HuffmanTree, distanceTree: HuffmanTree): void {
    while (true) {
        const symbol = literalLengthTree.decode(reader);
        if (symbol < 256) {
            output.writeByte(symbol);
            continue;
        }
        if (symbol === 256) {
            return;
        }
        if (symbol > 285) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Verify the payload begins with a valid zlib header (CMF=0x78 etc.) — if not, you are feeding raw deflate or gzip
  2. Check the compressed byte count in the FBX array property header is used as the slice length, not the uncompressed length
  3. Compare with python zlib.decompress(payload) to confirm whether the payload itself is broken
  4. Re-transfer the file in binary mode / re-export from the source tool

Example fix

// before
const raw = data.subarray(pos);            // includes adler32 of nothing / wrong span
// after
const payload = data.subarray(pos, pos + compressedLen);
const out = inflateZlib(payload, uncompressedLen);
Defensive patterns

Strategy: validation

Validate before calling

// Confirm zlib wrapper presence before inflating
if (!(payload[0] === 0x78 || payload[0] === 0x08)) {
  throw new Error("Payload does not look zlib-wrapped; check slicing");
}

Type guard

function hasZlibHeader(d: Uint8Array): d is Uint8Array & { length: number } {
  return d.byteLength >= 2 && (d[0] & 0x0f) === 8 && ((d[0] << 8) + d[1]) % 31 === 0;
}

Try / catch

try {
  const out = inflateZlib(payload, expectedLength);
} catch (e) {
  if (e instanceof Error && e.message === "deflate: invalid stored block length") {
    throw new Error("Stored block LEN/NLEN mismatch — payload offset or format is wrong", { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: inflateZlib encounters blockType 0 and inflateStoredBlock reads two uint16 LE values whose XOR is not 0xffff — the bitstream position is misaligned (wrong payload offset, or a previous block was parsed from wrong bytes) or the data is corrupt.

Common situations: Passing raw deflate (no zlib wrapper) or gzip data to inflateZlib; slicing an FBX array payload starting at the wrong byte; FBX files altered by a lossy transfer (text-mode FTP, encoding conversion).

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/081b03820b76877a. Report an issue: GitHub.