google/ExoPlayer · error · GlException
glError: {gluErrorString(error)}
Error message
glError: {gluErrorString(error)} What it means
GlUtil.checkGlError() drains ALL pending GLES errors with glGetError() and throws a GlException listing each as 'glError: <string>' (via gluErrorString). GL errors are sticky and set by any preceding GLES call, so this exception rarely points at the line that caused it — it points at the first place that checked. Each message line corresponds to one deferred error code such as GL_INVALID_ENUM, GL_INVALID_VALUE, GL_INVALID_OPERATION, or GL_OUT_OF_MEMORY.
Source
Thrown at library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java:418
}
/**
* Collects all OpenGL errors that occurred since this method was last called and throws a {@link
* GlException} with the combined error message.
*/
public static void checkGlError() throws GlException {
StringBuilder errorMessageBuilder = new StringBuilder();
boolean foundError = false;
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
if (foundError) {
errorMessageBuilder.append('\n');
}
errorMessageBuilder.append("glError: ").append(gluErrorString(error));
foundError = true;
}
if (foundError) {
throw new GlException(errorMessageBuilder.toString());
}
}
/**
* Asserts the texture size is valid.
*
* @param width The width for a texture.
* @param height The height for a texture.
* @throws GlException If the texture width or height is invalid.
*/
private static void assertValidTextureSize(int width, int height) throws GlException {
// TODO(b/201293185): Consider handling adjustments for sizes > GL_MAX_TEXTURE_SIZE
// (ex. downscaling appropriately) in a shader program instead of asserting incorrect
// values.
// For valid GL sizes, see:
// https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glTexImage2D.xml
int[] maxTextureSizeBuffer = new int[1];
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeBuffer, 0);View on GitHub (pinned to dd430f7053)
Solutions
- Reproduce with a GL call tracer (Android GPU Inspector or 'adb shell dumpsys gfxinfo ... framestats'/GPU profiling) to find the actual failing GLES call before the checkGlError() site
- Validate every texture size against GlUtil.maxTextureSize()/assertValidTextureSize expectations and use power-of-2-friendly/row-aligned sizes for uncompressed uploads
- Ensure an EGL context is current and all GL work runs on the single GL thread that owns the context; never share GL objects across contexts without EGL share-groups
- If GL_OUT_OF_MEMORY: reduce output resolution/bitrate in the Transformer/effects configuration (e.g. 1080p instead of 4K) for that device
- Update media3/GLES drivers: several INVALID_VALUE bugs on specific OEM drivers are worked around in newer releases
Example fix
// before int texId = GlUtil.createTexture(GLES20.GL_TEXTURE_2D, 5000, 3000, false); // > max on device -> later glError // after int max = GlUtil.maxTextureSize(); int w = Math.min(width, max), h = Math.min(height, max); int texId = GlUtil.createTexture(GLES20.GL_TEXTURE_2D, w, h, false);
Defensive patterns
Strategy: try-catch
Validate before calling
int err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) {
// clear or abort before invoking GlUtil helpers
} Try / catch
try { glOperation(); } catch (GlException e) { /* messages are prefixed 'glError:'; log per-line, release GL objects, abort the frame */ } Prevention
- Drain glGetError yourself between your own GL blocks so errors are attributed correctly
- Keep all GL work on one thread with one current context
- Clamp texture sizes to GlUtil.maxTextureSize() at creation
When it happens
Trigger: Any preceding GLES20/GLES11Ext call on the same thread/context passed invalid arguments: binding a deleted texture id (GL_INVALID_OPERATION), glTexImage2D with non-multiple-of-4 width on uncompressed formats (GL_INVALID_VALUE), using a uniform location from a different program, enabling a capability in the wrong state, or GL_OUT_OF_MEMORY when allocating large textures — then any later GlUtil call that invokes checkGlError() (createTexture, focusFramebuffer, GlProgram.draw, etc.) surfaces them.
Common situations: Device-specific driver quirks (especially on cheap SoCs/emulators), shader compile/link issues surfacing as draw-time INVALID_OPERATION, textures exceeding device max size, calling GL methods without a current EGL context, and interleaving third-party GL code that leaves errors pending before ExoPlayer's GL utility runs.
Related errors
- No call to setSamplerTexId() before bind.
- Unexpected uniform type: {type}
- width or height is less than 0
- Unsupported color transfer: {colorTransfer}
- eglCreateContext() failed to create a valid context. The dev
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/d494d4ddff5527eb.
Report an issue: GitHub.