BabylonJS/Babylon.js · error · Error

First chunk format is not JSON

Error message

First chunk format is not JSON

What it means

Thrown while unpacking a glTF binary v2 container when the first chunk's format uint32 is not ChunkFormat.JSON (0x4E4F534A, 'JSON'). The glb spec mandates the JSON chunk come first.

Source

Thrown at packages/dev/loaders/src/glTF/glTFFileLoader.pure.ts:1334

                readAsync: (byteOffset, byteLength) => dataReader.buffer.readAsync(startByteOffset + byteOffset, byteLength),
                byteLength: bodyLength,
            };
        }

        return Promise.resolve(data);
    }

    private _unpackBinaryV2Async(dataReader: DataReader, length: number): Promise<IGLTFLoaderData> {
        const ChunkFormat = {
            JSON: 0x4e4f534a,
            BIN: 0x004e4942,
        };

        // Read the JSON chunk header.
        const chunkLength = dataReader.readUint32();
        const chunkFormat = dataReader.readUint32();
        if (chunkFormat !== ChunkFormat.JSON) {
            throw new Error("First chunk format is not JSON");
        }

        // Bail if there are no other chunks.
        if (dataReader.byteOffset + chunkLength === length) {
            return dataReader.loadAsync(chunkLength).then(() => {
                return { json: this._parseJson(dataReader.readString(chunkLength)), bin: null };
            });
        }

        // Read the JSON chunk and the length and type of the next chunk.
        return dataReader.loadAsync(chunkLength + 8).then(() => {
            const data: IGLTFLoaderData = { json: this._parseJson(dataReader.readString(chunkLength)), bin: null };

            const readAsync = (): Promise<IGLTFLoaderData> => {
                const chunkLength = dataReader.readUint32();
                const chunkFormat = dataReader.readUint32();

                switch (chunkFormat) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Re-export the .glb with a spec-compliant tool so the JSON chunk is first
  2. Hex-inspect the chunk header at byte 12–20 and correct the format field
  3. Run glTF-Validator on the file to confirm container layout
Defensive patterns

Strategy: validation

Validate before calling

const dv = new DataView(await file.arrayBuffer());
if (dv.getUint32(0, true) !== 0x46546c67) throw new Error('not glb');
if (dv.getUint32(4, true) === 2 && dv.getUint32(16, true) !== 0x4e4f534a) {
  throw new Error('First glb-v2 chunk is not JSON');
}

Type guard

function firstChunkIsJson(buf: ArrayBuffer): boolean {
  return new DataView(buf).getUint32(16, true) === 0x4e4f534a; // 'JSON'
}

Try / catch

try {
  await loader.loadAsync(url);
} catch (e) {
  if (e.message === 'First chunk format is not JSON') {
    console.error('glb chunk order violated — re-export with a compliant tool');
  }
}

Prevention

When it happens

Trigger: Loading a .glb whose first chunk header declares a non-JSON format (e.g. BIN first, or a corrupted format value).

Common situations: Custom .glb writers that emit the BIN chunk first; files corrupted in transfer/storage; tools writing v1 layout into a v2 header.

Related errors


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