WebGL Error Constants

WebGL error constants (gl.INVALID_ENUM, etc.) with numeric value and cause.

Reference for the WebGL error constants returned by gl.getError(), each with its numeric value, meaning and the typical mistake that triggers it, plus a searchable lookup by name or code. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What does gl.getError() return when there is no error?

It returns gl.NO_ERROR, which equals 0. After returning any error code, the internal error flag is reset to NO_ERROR, so each error is reported only once per getError() call.

Decode any gl.getError() result

WebGL surfaces problems through a single error flag you read with gl.getError(), which returns one of a small set of integer constants. This reference lists every standard WebGL 1 and WebGL 2 error constant with its hexadecimal value, plain-English meaning and the most common coding mistake that produces it — searchable by name or code.

How it works

WebGL keeps an internal error flag. When an API call fails, the flag is set to the matching error enum. Calling gl.getError() returns the current flag and resets it to gl.NO_ERROR. The constants are plain numbers shared with desktop OpenGL:

const err = gl.getError();
if (err !== gl.NO_ERROR) {
  console.warn("WebGL error", err.toString(16));
}

Because the flag clears on read, call getError() immediately after the suspect operation. Several errors can be pending; in that case the order of reporting is implementation-defined, so fix the first one and re-check.

Error constants in detail

NO_ERROR (0x0000)

No error has been recorded. The normal state of gl.getError() when all calls succeed. Always compare with gl.NO_ERROR, not a falsy check — the value is 0, which is falsy, but conceptually it means success.

INVALID_ENUM (0x0500)

An argument to an API call is not an accepted enum value for that parameter. For example, passing a string where an enum constant is expected, or passing the wrong texture target to gl.texImage2D. Check the WebGL specification for which enums are valid for each parameter — many parameters accept only a subset of all enum constants.

INVALID_VALUE (0x0501)

A numeric argument is outside the valid range. Common triggers: negative texture dimensions, a stride value that is not a multiple of the component size, a level of detail outside the valid mipmap range, or an out-of-bounds uniform location. The value is technically a number but fails a range or alignment check.

INVALID_OPERATION (0x0502)

The most common error, and the most context-dependent. It means the command is not allowed in the current WebGL state. Typical causes:

  • Drawing with no program linked and in use. Call gl.useProgram(program) before any draw call.
  • Sampling a texture that is not texture-complete. A 2D texture is complete only if it has a full mipmap chain OR if gl.TEXTURE_MIN_FILTER is set to LINEAR or NEAREST (non-mipmapping). Missing mipmap levels produce INVALID_OPERATION or silently render black pixels depending on the driver.
  • Mismatched uniform type. Calling gl.uniform1f on a uniform that the shader declares as int or sampler2D.
  • Framebuffer incomplete. Drawing to a framebuffer object that is not framebuffer-complete. Check gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE before rendering to an FBO.
  • Buffer not bound. Calling gl.drawElements or gl.drawArrays with a vertex attribute enabled that has no buffer bound to it.

INVALID_FRAMEBUFFER_OPERATION (0x0506)

The framebuffer object is not framebuffer-complete at the time of a read or draw call. This is distinct from INVALID_OPERATION and specifically signals an incomplete framebuffer. Causes include a color attachment without a backing texture or renderbuffer, mismatched attachment sizes, or a depth/stencil format that the implementation does not support.

OUT_OF_MEMORY (0x0505)

The implementation ran out of GPU memory for the operation. After this error, the state of the object being operated on is undefined. The safest recovery is to destroy and recreate the object entirely. This error can occur during large texture allocation, buffer uploads, or shader compilation of complex shaders.

CONTEXT_LOST_WEBGL (0x9242)

The GPU context was reset. After a context loss, all WebGL resources — textures, buffers, programs, framebuffers — are invalid and must be recreated from scratch. Context loss can be triggered by a GPU driver reset, the OS reclaiming GPU resources when the browser tab is backgrounded, or creating too many WebGL contexts simultaneously.

Handle context loss by listening for the webglcontextlost event, calling event.preventDefault() to signal that you will restore the context, and then recreating all resources in the webglcontextrestored event:

canvas.addEventListener('webglcontextlost', (event) => {
  event.preventDefault();
  cancelAnimationFrame(animFrameId);
}, false);

canvas.addEventListener('webglcontextrestored', () => {
  initWebGL(); // recreate shaders, textures, buffers
}, false);

Debugging workflow

  1. After a suspicious call, read gl.getError() immediately. The flag resets on read.
  2. Use WEBGL_debug_renderer_info to log the GPU vendor and renderer string — helps distinguish driver-specific bugs.
  3. In development, use a WebGL debug shim like the one from khronos/WebGLDeveloperTools, which wraps every call with automatic error checking and logs detailed messages.
  4. For shader compile errors, always check gl.getShaderInfoLog(shader) after gl.compileShader — shader errors surface in the info log, not through getError.

Tips and notes

  • NO_ERROR is 0 — always compare against gl.NO_ERROR, never a truthy check.
  • INVALID_OPERATION is a state error: usually a missing bind, incomplete framebuffer, or type mismatch.
  • OUT_OF_MEMORY may leave the GL object in an undefined state — recreate it.
  • After CONTEXT_LOST_WEBGL, all textures, buffers and programs are invalid. Always handle context loss in production apps.
  • Wrap calls with a debug context in development for richer messages than getError alone provides.