BabylonJS/Babylon.js · error · Error

Error in HufUnpackEncTable

Error message

Error in HufUnpackEncTable

What it means

HufUnpackEncTable decodes the Huffman encoder table from an EXR file's compressed pixel data. When it encounters a LONG_ZEROCODE_RUN, the run-length count must fit within the remaining code entries (ni). If the decoded run would exceed the table, the data is corrupt or malformed, so the loader throws this error rather than producing a broken Huffman table.

Source

Thrown at packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.compression.huf.ts:232

    let c = 0;
    let lc = 0;

    for (; im <= iM; im++) {
        if (p.value - offset.value > ni) {
            return;
        }

        let gb = GetBits(6, c, lc, array, p);

        const l = gb.l;
        c = gb.c;
        lc = gb.lc;

        hcode[im] = l;

        if (l == LONG_ZEROCODE_RUN) {
            if (p.value - offset.value > ni) {
                throw new Error("Error in HufUnpackEncTable");
            }

            gb = GetBits(8, c, lc, array, p);

            let zerun = gb.l + SHORTEST_LONG_RUN;
            c = gb.c;
            lc = gb.lc;

            if (im + zerun > iM + 1) {
                throw new Error("Error in HufUnpackEncTable");
            }

            while (zerun--) {
                hcode[im++] = 0;
            }

            im--;
        } else if (l >= SHORT_ZEROCODE_RUN) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Re-obtain/verify the EXR file: check integrity (file size, checksum) and re-download; confirm it opens in a tool like OpenEXR's exrheader/exrdisplay
  2. Confirm the EXR uses a supported compression and is a valid OpenEXR v2 file; re-export/convert it (e.g., with `oiiotool in.exr -o out.exr`)
  3. Verify the server serves the complete binary with correct Content-Type (image/avax) and no encoding/transformation mangling the bytes
  4. If the file is known-good, report to Babylon.js with the failing EXR; meanwhile load a losslessly re-encoded (e.g., ZIP-compressed) version

Example fix

// before
const cube = CubeTexture.Load('scene/env.hdr.exr'); // corrupt file -> throws in HufUnpackEncTable
// after
fetch('scene/env.exr')
  .then((r) => { if (!r.ok || !Number(r.headers.get('content-length'))) throw new Error('incomplete EXR'); return r.blob(); })
  .then((b) => { /* verify integrity, then load */ });
Defensive patterns

Strategy: validation

Validate before calling

async function loadVerifiedExr(url: string, scene: BABYLON.Scene): Promise<BABYLON.BaseTexture> {
    const res = await fetch(url);
    if (!res.ok) throw new Error(`EXR fetch failed: ${res.status}`);
    const buf = await res.arrayBuffer();
    const magic = new Uint8Array(buf, 0, 4);
    const isExr = magic[0] === 0x76 && magic[1] === 0x2f && magic[2] === 0x31 && magic[3] === 0x01;
    if (!isExr || buf.byteLength === 0) throw new Error('Corrupt or non-EXR payload');
    return new BABYLON.CubeTexture(url, scene);
}

Type guard

function isOpenExrBuffer(buf: ArrayBuffer): boolean {
    if (buf.byteLength < 4) return false;
    const m = new Uint8Array(buf, 0, 4);
    return m[0] === 0x76 && m[1] === 0x2f && m[2] === 0x31 && m[3] === 0x01;
}

Try / catch

try {
    const texture = new BABYLON.CubeTexture('env.exr', scene);
    return texture;
} catch (e) {
    if (String(e?.message).includes('HufUnpackEncTable')) {
        console.error('EXR huf data corrupt; re-download or re-encode the asset', e);
        return null; // or load .env fallback
    }
    throw e;
}

Prevention

When it happens

Trigger: Loading a corrupt/truncated EXR file (compression type with huf compression, e.g., PIZ/PIZ_COMPRESSION or DWA) whose huf compressed table contains a long zero-code run longer than the number of remaining entries.

Common situations: EXR downloaded incompletely (truncated HTTP body); EXR produced by a buggy encoder; corrupted file from transfer/storage; wrong bytes served (HTML error page or wrong content-type) parsed as EXR.

Related errors


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