BabylonJS/Babylon.js · error
${context}: Uri is missing or the binary glTF is missing its
Error message
${context}: Uri is missing or the binary glTF is missing its binary chunk What it means
With MSFT_lod + range requests (HTTP range loading), buffer data must come either from a uri or from the .glb binary chunk. When useRangeRequests is enabled, the buffer has no uri, and the loader has no bin chunk stored (e.g. the .glb lacked its BIN chunk or a .gltf was loaded with range requests), there is no data source and loadBufferAsync throws.
Source
Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.pure.ts:310
this._loader.log(`deferred`);
const previousIndexLOD = this._materialIndexLOD - 1;
this._materialSignalLODs[previousIndexLOD] = this._materialSignalLODs[previousIndexLOD] || new Deferred<void>();
return this._materialSignalLODs[previousIndexLOD].promise.then(async () => {
return await this._loader.loadUriAsync(context, property, uri);
});
}
return null;
}
/**
* @internal
*/
// eslint-disable-next-line no-restricted-syntax
public loadBufferAsync(context: string, buffer: IBuffer, byteOffset: number, byteLength: number): Nullable<Promise<ArrayBufferView>> {
if (this._loader.parent.useRangeRequests && !buffer.uri) {
if (!this._loader.bin) {
throw new Error(`${context}: Uri is missing or the binary glTF is missing its binary chunk`);
}
const loadAsync = async (bufferLODs: Array<IBufferInfo>, indexLOD: number) => {
const start = byteOffset;
const end = start + byteLength - 1;
let bufferLOD = bufferLODs[indexLOD];
if (bufferLOD) {
bufferLOD.start = Math.min(bufferLOD.start, start);
bufferLOD.end = Math.max(bufferLOD.end, end);
} else {
bufferLOD = { start: start, end: end, loaded: new Deferred() };
bufferLODs[indexLOD] = bufferLOD;
}
return await bufferLOD.loaded.promise.then((data) => {
return new Uint8Array(data.buffer, data.byteOffset + byteOffset - bufferLOD.start, byteLength);
});
};
View on GitHub (pinned to 0592b347b8)
Solutions
- Use a .glb file that contains a valid binary (BIN) chunk when useRangeRequests is true.
- Add a uri to the buffer in the glTF so it can be fetched directly.
- Disable useRangeRequests (loader.parent.useRangeRequests = false) if full files are available.
Example fix
// before loader.useRangeRequests = true; // loading .gltf without buffer uri // after loader.useRangeRequests = true; // with .glb containing BIN chunk // or: loader.useRangeRequests = false;
Defensive patterns
Strategy: fallback
Validate before calling
if (loader.useRangeRequests && !isGlb(bufferSource)) {
throw new Error('Range requests require a .glb with a binary chunk');
} Try / catch
try { await loader.loadAsync(url); } catch (e) {
if (e.message.includes('binary chunk')) {
loader.useRangeRequests = false;
return loader.loadAsync(url); // fallback without range requests
} throw e;
} Prevention
- Only enable useRangeRequests with .glb files containing a BIN chunk.
- Verify buffers either have uri or rely on the binary chunk, not neither.
- Confirm the server supports HTTP Range headers before enabling range loading.
When it happens
Trigger: Loading with MSFT_lod extension and loader.parent.useRangeRequests = true where buffer.uri is absent AND loader.bin is null (glb without binary chunk, or range requests on a plain .gltf).
Common situations: Enabling useRangeRequests for LOD streaming on .gltf files (JSON-only) instead of .glb; stripping the BIN chunk from a .glb during optimization; serving .glb files without proper range support and combining configs incorrectly.
Related errors
- Buffer access is out of range
- maxLODsToLoad must be greater than zero
- ${context}: Uri is missing or the binary glTF is missing its
- ${context}: ${e.message}
- BufferView ${bufferView} not found in BufferManager.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/26c7f048191b19b0.
Report an issue: GitHub.