BabylonJS/Babylon.js · error
zlib: invalid header
Error message
zlib: invalid header
What it means
The first two bytes of a zlib stream (CMF/FLG) must declare the deflate method (CMF&0x0f === 8), window size ≤ 32K (CMF>>4 ≤ 7), and pass the header checksum ((CMF<<8|FLG) % 31 === 0). inflateZlib throws 'zlib: invalid header' when the buffer's first bytes are not a valid zlib header.
Source
Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:28
/**
* Inflate a zlib-wrapped deflate stream.
*
* This implementation is intentionally scoped to FBX binary array payloads: one-shot,
* synchronous zlib streams with the exact uncompressed length known up front.
*/
export function inflateZlib(input: Uint8Array, expectedLength: number): Uint8Array {
if (!Number.isInteger(expectedLength) || expectedLength < 0) {
throw new Error("zlib: invalid expected length");
}
if (input.byteLength < 6) {
throw new Error("zlib: unexpected end of input");
}
const cmf = input[0];
const flg = input[1];
if ((cmf & 0x0f) !== 8 || cmf >> 4 > 7 || ((cmf << 8) + flg) % 31 !== 0) {
throw new Error("zlib: invalid header");
}
if ((flg & 0x20) !== 0) {
throw new Error("zlib: preset dictionary not supported");
}
const reader = new BitReader(input, 2, input.byteLength - 4);
const output = new OutputWriter(expectedLength);
let isFinalBlock = false;
while (!isFinalBlock) {
isFinalBlock = reader.readBits(1) === 1;
const blockType = reader.readBits(2);
switch (blockType) {
case 0:
inflateStoredBlock(reader, output);
break;
case 1:
inflateCompressedBlock(reader, output, getFixedLiteralLengthTree(), getFixedDistanceTree());
View on GitHub (pinned to 0592b347b8)
Solutions
- Confirm the FBX record's encoding flag matches its actual content — re-export the file from the original tool
- Check the byte offset used to locate the compressed payload; off-by-N errors surface as header failures
- Inspect the first bytes: a valid zlib stream starts with 0x78 typically; 0x1F8B means gzip, plain text means not compressed
- Validate with a reference FBX reader; if it also fails, the file is malformed
Example fix
// before
const compressed = bytes.slice(offset + 4, offset + len);
// after
const compressed = bytes.slice(offset, offset + len); // correct header offset
if (compressed[0] !== 0x78) console.warn('FBX array payload is not zlib data at offset', offset); Defensive patterns
Strategy: validation
Validate before calling
function looksLikeZlib(b: Uint8Array): boolean {
if (b.byteLength < 2) return false;
const cmf = b[0], flg = b[1];
return (cmf & 0x0f) === 8 && (cmf >> 4) <= 7 && ((cmf << 8) + flg) % 31 === 0;
}
if (!looksLikeZlib(compressed)) throw new Error('FBX array payload is not zlib data'); Type guard
function isZlibStream(b: Uint8Array): boolean {
return b.byteLength >= 2 && (b[0] & 0x0f) === 8 && (b[0] >> 4) <= 7 && ((b[0] << 8) + b[1]) % 31 === 0;
} Try / catch
try {
return inflateZlib(compressed, expectedLength);
} catch (e) {
if ((e as Error).message === 'zlib: invalid header') {
throw new Error('FBX compressed array does not contain a valid zlib stream', { cause: e });
}
throw e;
} Prevention
- Check the first byte is 0x78-family before inflating
- Ensure the compressed region starts at the correct record offset
- Avoid pipelines that relabel gzip/lzma data as zlib
When it happens
Trigger: parseArrayProperty hands inflateZlib bytes that are not actually zlib-compressed — e.g., an FBX record with encoding set to 1 but raw/uncompressed data, data starting at the wrong offset (off-by-a-few-bytes), or a differently-compressed payload (gzip, lzma) mislabeled as zlib.
Common situations: FBX files written by non-standard exporters that set the encoding flag without actually zlib-compressing; misaligned parsing due to a bad earlier field; assets processed by a pipeline that recompressed arrays with a different codec.
Related errors
- zlib: trailing deflate data
- zlib: invalid expected length
- zlib: unexpected end of input
- zlib: preset dictionary not supported
- zlib: adler32 mismatch
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/24a408c4862fbf29.
Report an issue: GitHub.