BabylonJS/Babylon.js · critical · Error
Unable to create index buffer
Error message
Unable to create index buffer
What it means
Thrown by createIndexBuffer when gl.createBuffer() returns null for an index buffer allocation — the driver failed to create the GL buffer object. Like error 108, it signals GPU resource exhaustion or a lost context, specific to the ELEMENT_ARRAY_BUFFER used for index data.
Source
Thrown at packages/dev/core/src/Engines/thinEngine.pure.ts:1368
protected _resetIndexBufferBinding(): void {
this.bindIndexBuffer(null);
this._cachedIndexBuffer = null;
}
/**
* Creates a new index buffer
* @param indices defines the content of the index buffer
* @param updatable defines if the index buffer must be updatable
* @param _label defines the label of the buffer (for debug purpose)
* @returns a new webGL buffer
*/
public createIndexBuffer(indices: IndicesArray, updatable?: boolean, _label?: string): DataBuffer {
const vbo = this._gl.createBuffer();
const dataBuffer = new WebGLDataBuffer(vbo);
if (!vbo) {
throw new Error("Unable to create index buffer");
}
this.bindIndexBuffer(dataBuffer);
const data = this._normalizeIndexData(indices);
this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, data, updatable ? this._gl.DYNAMIC_DRAW : this._gl.STATIC_DRAW);
this._resetIndexBufferBinding();
dataBuffer.references = 1;
dataBuffer.is32Bits = data.BYTES_PER_ELEMENT === 4;
return dataBuffer;
}
protected _normalizeIndexData(indices: IndicesArray): Uint16Array | Uint32Array {
const bytesPerElement = (indices as Exclude<IndicesArray, number[]>).BYTES_PER_ELEMENT;
if (bytesPerElement === 2) {
return indices as Uint16Array;
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Check gl.isContextLost() and handle context restoration if lost
- Dispose unused meshes/index buffers to free GPU memory before retrying
- Use 16-bit indices where vertex count < 65536 to shrink buffer size
- Reuse existing DataBuffers (updateVertexBuffer patterns) instead of allocating new ones per frame
Example fix
// before
mesh.setIndices(newIndices); // creates a new 32-bit index buffer each frame
// after
if (maxIndex < 65536) mesh.setIndices(newIndices, true); // updatable 16-bit buffer reused
else { oldBuffer.dispose(); mesh.setIndices(newIndices); } Defensive patterns
Strategy: validation
Validate before calling
function canAllocateBuffer(gl: WebGLRenderingContext): boolean {
return !gl.isContextLost() && gl.getError() === gl.NO_ERROR;
} Type guard
null
Try / catch
try {
const ib = engine.createIndexBuffer(indices);
} catch (e) {
if ((e as Error).message === 'Unable to create index buffer') {
freeGpuMemory();
ib = engine.createIndexBuffer(indices); // retry once
} else throw e;
} Prevention
- Use 16-bit indices when vertex count allows (< 65536)
- Reuse and update existing index buffers instead of recreating them per frame
- Dispose old geometry before uploading replacements
- Handle context-lost events; lost contexts make createBuffer return null
When it happens
Trigger: gl.createBuffer() returning null while creating index buffers: GPU memory exhausted, context lost, driver limits hit — typically on scenes with very large index arrays (32-bit indices for high-poly meshes).
Common situations: High-poly meshes requiring 32-bit index buffers on low-VRAM devices; repeatedly creating index buffers for dynamic geometry without disposing the old ones; context loss on mobile during heavy scenes.
Related errors
- Unable to create vertex buffer
- Unable to create multi sampled framebuffer
- Unable to create instance buffer
- Atmosphere is not supported on WebGL ${engine.version}.
- Instanced arrays are required for MSDF text rendering.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/5d37c646312ecc78.
Report an issue: GitHub.