BabylonJS/Babylon.js · error · RuntimeError
GLTFLoaderUnexpectedMagicError
GLTFLoaderUnexpectedMagicError
Error message
Unexpected magic:
What it means
Thrown as a RuntimeError (code GLTFLoaderUnexpectedMagicError) when the first 4 bytes of a binary glTF file do not equal the magic number 0x46546C67 ('glTF'). The loader uses this constant to confirm the stream is a binary glTF container.
Source
Thrown at packages/dev/loaders/src/glTF/glTFFileLoader.pure.ts:1263
this._startPerformanceCounter("Parse JSON");
this._log(`JSON length: ${json.length}`);
const parsed = JSON.parse(json);
this._endPerformanceCounter("Parse JSON");
return parsed;
}
private _unpackBinaryAsync(dataReader: DataReader): Promise<IGLTFLoaderData> {
this._startPerformanceCounter("Unpack Binary");
// Read magic + version + length + json length + json format
return dataReader.loadAsync(20).then(() => {
const Binary = {
Magic: 0x46546c67,
};
const magic = dataReader.readUint32();
if (magic !== Binary.Magic) {
throw new RuntimeError("Unexpected magic: " + magic, ErrorCodes.GLTFLoaderUnexpectedMagicError);
}
const version = dataReader.readUint32();
if (this.loggingEnabled) {
this._log(`Binary version: ${version}`);
}
const length = dataReader.readUint32();
if (!this.useRangeRequests && length !== dataReader.buffer.byteLength) {
Logger.Warn(`Length in header does not match actual data length: ${length} != ${dataReader.buffer.byteLength}`);
}
let unpacked: Promise<IGLTFLoaderData>;
switch (version) {
case 1: {
unpacked = this._unpackBinaryV1Async(dataReader, length);
break;
View on GitHub (pinned to 0592b347b8)
Solutions
- Verify the URL returns an actual .glb file (check first bytes are 'glTF')
- Check the HTTP response status/content-type and fix server routing so errors aren't served as 200
- Re-download/re-export the file — it may be corrupted or truncated
Example fix
// before
scene.importMeshesFromMeshesAsync("model.gltf.url/that/404s.glb"); // server returns HTML 200
// after
const res = await fetch(url);
if (!res.ok || !(await res.arrayBuffer()).byteLength) throw new Error("bad asset");
await scene.importMeshesFromMeshesAsync(url); Defensive patterns
Strategy: retry
Prevention
- Add a download integrity check (size + magic bytes) before handing buffers to the loader
When it happens
Trigger: Calling a load path that expects binary glTF (.glb) but the fetched bytes are JSON text, HTML (e.g. a 404 page), or a truncated file.
Common situations: Server returning an HTML error page with 200 status; wrong file extension/URL; serving .gltf JSON to a .glb path; gzip/CDN mangling the bytes.
Related errors
- Unexpected content format: ${contentFormat}
- First chunk format is not JSON
- Unexpected JSON chunk
- Expected opening { after type & name
- Expected OFFSET, but got:
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/e472c427cc057130.
Report an issue: GitHub.