BabylonJS/Babylon.js · error

Unexpected JSON chunk

Error message

Unexpected JSON chunk

What it means

Thrown in the v2 chunk loop when a chunk with format ChunkFormat.JSON is encountered after the first (JSON) chunk. The glb spec allows only one JSON chunk, and it must be first; a second one is invalid.

Source

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

        // 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) {
                    case ChunkFormat.JSON: {
                        throw new Error("Unexpected JSON chunk");
                    }
                    case ChunkFormat.BIN: {
                        const startByteOffset = dataReader.byteOffset;
                        data.bin = {
                            readAsync: (byteOffset, byteLength) => dataReader.buffer.readAsync(startByteOffset + byteOffset, byteLength),
                            byteLength: chunkLength,
                        };
                        dataReader.skipBytes(chunkLength);
                        break;
                    }
                    default: {
                        // ignore unrecognized chunkFormat
                        dataReader.skipBytes(chunkLength);
                        break;
                    }
                }

                if (dataReader.byteOffset !== length) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Rebuild the .glb with a single JSON chunk followed by BIN chunk(s) using glTF-Transform
  2. Remove the duplicate/extra JSON chunk from the container
  3. Validate with glTF-Validator; re-export from the original source asset
Defensive patterns

Strategy: validation

Validate before calling

function countJsonChunks(buf) {
  const dv = new DataView(buf);
  let off = 20, count = 0;
  while (off + 8 <= dv.byteLength) {
    const len = dv.getUint32(off, true), fmt = dv.getUint32(off + 4, true);
    if (fmt === 0x4e4f534a) count++;
    off += 8 + len;
  }
  return count;
}
if (countJsonChunks(await file.arrayBuffer()) > 1) throw new Error('Duplicate JSON chunk');

Try / catch

try {
  await loader.loadAsync(url);
} catch (e) {
  if (e.message === 'Unexpected JSON chunk') {
    console.error('glb contains a second JSON chunk — rebuild the container');
  }
}

Prevention

When it happens

Trigger: Loading a .glb containing two JSON chunks — e.g. a concatenation of files or a custom writer duplicating the metadata chunk.

Common situations: Naive merge scripts appending two glbs; buggy chunk-splitting tools; corrupted multi-chunk files.

Related errors


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