BabylonJS/Babylon.js · error
deflate: distance out of range
Error message
deflate: distance out of range
What it means
OutputWriter.copy validates that a back-reference distance is within the bytes already written: distance must be > 0 and <= the current output offset. A distance beyond what has been emitted is illegal in DEFLATE (it would read from the pre-output prefix shared with the compressor), so the library throws. This always indicates a corrupt or non-deflate bitstream, since a valid compressor never emits such a distance.
Source
Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:168
public constructor(expectedLength: number) {
this.bytes = new Uint8Array(expectedLength);
}
public writeByte(value: number): void {
if (this.offset >= this.bytes.byteLength) {
throw new Error("zlib: output length mismatch");
}
const byte = value & 0xff;
this.bytes[this.offset++] = byte;
this.adlerA += byte;
this.adlerB += this.adlerA;
this.adlerA %= ADLER_MOD;
this.adlerB %= ADLER_MOD;
}
public copy(distance: number, length: number): void {
if (distance <= 0 || distance > this.offset) {
throw new Error("deflate: distance out of range");
}
for (let i = 0; i < length; i++) {
this.writeByte(this.bytes[this.offset - distance]);
}
}
public finish(): void {
if (this.offset !== this.bytes.byteLength) {
throw new Error("zlib: output length mismatch");
}
}
public adler32(): number {
return ((this.adlerB << 16) | this.adlerA) >>> 0;
}
}
class HuffmanTree {
View on GitHub (pinned to 0592b347b8)
Solutions
- Treat the file as corrupt first: try inflating it with pako or Node's zlib to confirm.
- Verify the payload slice starts exactly at the compressed data (2-byte zlib header), not at an arbitrary offset.
- Re-download/re-export the FBX file; check git LFS pointers and merge states for binary assets.
- If you control the producer, regenerate the compressed payload with a standard zlib implementation.
Example fix
// before const payload = buffer.subarray(nodeOffset + 8, ...); // wrong start, mid-stream // after const payload = buffer.subarray(nodeOffset, nodeOffset + compressedLength); // header-aligned start inflateZlib(payload, count);
Defensive patterns
Strategy: try-catch
Validate before calling
function hasValidZlibHeader(buf: Uint8Array): boolean {
return buf.byteLength >= 6 && (buf[0] & 0x0f) === 8 && buf[0] >> 4 <= 7 && ((buf[0] << 8) + buf[1]) % 31 === 0;
}
if (!hasValidZlibHeader(payload)) throw new Error("not a zlib stream"); Type guard
function isZlib(buf: unknown): buf is Uint8Array {
return buf instanceof Uint8Array && buf.byteLength >= 6 && ((buf[0] << 8) + buf[1]) % 31 === 0;
} Try / catch
try {
return inflateZlib(payload, count);
} catch (e) {
if (e instanceof Error && e.message === "deflate: distance out of range") {
throw new Error("corrupt deflate stream (illegal back-reference) — re-export the FBX asset");
}
throw e;
} Prevention
- Start inflation exactly at the zlib header, never mid-stream.
- Verify binary assets in git LFS / merge states; bad merges corrupt payloads.
- Cross-validate suspicious files with Node zlib or pako.
- Never hand-edit compressed FBX array payloads.
When it happens
Trigger: inflateCompressedBlock decodes a length/distance pair whose decoded distance exceeds the number of bytes written so far — bitstream desynchronization (e.g. after a truncated read or wrong tree), or input that is not actually deflate data.
Common situations: Corrupted downloads where mid-stream bits flip; passing a random byte blob that passed the zlib header coincidence test; mixing up payload offsets so the inflater starts mid-stream; FBX assets damaged by faulty binary-merge tooling (git LFS/merge conflicts).
Related errors
- deflate: invalid block type
- zlib: invalid header
- zlib: trailing deflate data
- zlib: adler32 mismatch
- deflate: expected byte alignment
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/0799b9544cd8ca1e.
Report an issue: GitHub.