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

  1. Check gl.isContextLost() and handle context restoration if lost
  2. Dispose unused meshes/index buffers to free GPU memory before retrying
  3. Use 16-bit indices where vertex count < 65536 to shrink buffer size
  4. 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

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


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