BabylonJS/Babylon.js · error
deflate: invalid distance symbol
Error message
deflate: invalid distance symbol
What it means
Distance symbols are valid in 0-29 in deflate. This error fires when distanceTree.decode returns a value above 29 (possible only with a fixed distance tree's 32-symbol space), i.e. the stream encoded an out-of-range distance code — the data is corrupt or being decoded with the wrong tree.
Source
Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:329
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) {
throw new Error("deflate: invalid literal/length symbol");
}
const lengthIndex = symbol - 257;
const length = LENGTH_BASE[lengthIndex] + reader.readBits(LENGTH_EXTRA_BITS[lengthIndex]);
const distanceSymbol = distanceTree.decode(reader);
if (distanceSymbol > 29) {
throw new Error("deflate: invalid distance symbol");
}
const distance = DISTANCE_BASE[distanceSymbol] + reader.readBits(DISTANCE_EXTRA_BITS[distanceSymbol]);
output.copy(distance, length);
}
}
function readDynamicTrees(reader: BitReader): {
literalLengthTree: HuffmanTree;
distanceTree: HuffmanTree;
} {
const literalLengthCount = reader.readBits(5) + 257;
const distanceCount = reader.readBits(5) + 1;
const codeLengthCount = reader.readBits(4) + 4;
const codeLengthLengths = new Array<number>(19).fill(0);
for (let i = 0; i < codeLengthCount; i++) {
codeLengthLengths[CODE_LENGTH_ORDER[i]] = reader.readBits(3);
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Confirm with python zlib.decompress(payload) whether the payload is genuinely valid zlib — most often the file is corrupt
- Verify the payload slice boundaries against the FBX array header's compressed byte count
- Re-export/re-download the FBX asset
- If reproducing from a specific file, dump the payload bytes around the failure offset to inspect whether it resembles compressed data at all
Defensive patterns
Strategy: try-catch
Validate before calling
// quick structural pre-check: zlib header + plausible size
if (!(((payload[0] << 8) + payload[1]) % 31 === 0 && (payload[0] & 0x0f) === 8)) {
throw new Error("Not a zlib stream");
} Type guard
function hasValidZlibHeader(d: Uint8Array): boolean {
return d.byteLength >= 2 && (d[0] & 0x0f) === 8 && d[0] >> 4 <= 7 && ((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 distance symbol") {
throw new Error("Invalid distance code in FBX compressed array — data corrupt", { cause: e });
}
throw e;
} Prevention
- Verify payload slice boundaries against the FBX array header
- Keep binary assets checksum-verified in storage/CI
- Test the same asset through a reference decompressor when diagnosing
When it happens
Trigger: inflateCompressedBlock decodes a length symbol, then distanceTree.decode(reader) returns 30 or 31 (fixed distance tree encodes 32 symbols of 5 bits each; the top two are illegal per RFC 1951).
Common situations: Decoding non-deflate bytes that happen to pass the zlib header check; corrupt FBX payload mid-block; wrong buffer slice causing bit misalignment so subsequent codes are garbage.
Related errors
- deflate: invalid huffman code
- deflate: invalid literal/length symbol
- deflate: invalid huffman code lengths
- deflate: invalid stored block length
- deflate: missing end-of-block code
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/2bbdf2f27057464d.
Report an issue: GitHub.