google/ExoPlayer · error · IllegalStateException
Unexpected uniform type: {type}
Error message
Unexpected uniform type: {type} What it means
Thrown from the default branch of GlProgram's uniform-binding switch when an active uniform in the linked program has a GL type the class does not know how to upload. Supported types are floats, ints/bools, vec2-4, matrices (MAT3/MAT4), and 2D samplers; anything else (e.g. GL_SAMPLER_CUBE, GL_IMAGE2D, arrays/half-float types, or a driver-reported exotic type) reaches the default case and throws IllegalStateException.
Source
Thrown at library/common/src/main/java/com/google/android/exoplayer2/util/GlProgram.java:440
break;
case GLES20.GL_SAMPLER_2D:
case GLES11Ext.GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
if (texIdValue == 0) {
throw new IllegalStateException("No call to setSamplerTexId() before bind.");
}
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + texUnitIndex);
GlUtil.checkGlError();
GlUtil.bindTexture(
type == GLES20.GL_SAMPLER_2D
? GLES20.GL_TEXTURE_2D
: GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
texIdValue);
GLES20.glUniform1i(location, texUnitIndex);
GlUtil.checkGlError();
break;
default:
throw new IllegalStateException("Unexpected uniform type: " + type);
}
}
}
}
View on GitHub (pinned to dd430f7053)
Solutions
- Remove the unsupported uniform from the shader, or split it into a second, standalone GLES20 program managed outside GlProgram
- Replace unsupported types with supported equivalents: samplerCube -> six 2D faces or pre-baked lookup; use setFloat/setFloats/setMat4 for data instead of exotic types
- Update to the latest media3 release where new uniform types have been added over time (check release notes for GlProgram changes)
- If the uniform is unused/dead code in GLSL, the compiler usually eliminates it — make sure it is actually referenced so it does not appear as active with a stray type
Example fix
// before
// fragment shader: uniform samplerCube uEnvMap; -> IllegalStateException on bind
// after
// fragment shader: uniform sampler2D uEnvMapFace; (upload one face as a 2D texture)
program.setSamplerTexId("uEnvMapFace", envFaceTexId, 0); Defensive patterns
Strategy: validation
Validate before calling
// After linking, verify every active uniform type is one GlProgram supports // (GL_FLOAT..GL_FLOAT_MAT4, GL_SAMPLER_2D, GL_SAMPLER_EXTERNAL_OES) before drawing; reject the shader early otherwise.
Try / catch
Catch IllegalStateException around draw() only to log which shader failed, then disable that effect — never continue rendering with a half-bound program.
Prevention
- Limit shaders used with GlProgram to plain float/int/vec/mat uniforms and 2D/external-OES samplers
- Run a shader smoke-test (compile, link, bind once) at app start or in CI with a GL context (e.g. Robolectric/Rotopeca or instrumentation)
When it happens
Trigger: A shader declares an unsupported uniform kind — samplerCube, sampler3D, image2D, or an arrayed uniform — and setUniformsAndBindTextures() iterates all active uniforms and hits the unknown type. Also possible on drivers that report unexpected types for half-precision uniforms.
Common situations: Porting a generic shader library to GlProgram (which only supports flat per-draw uniforms), using cubemaps for environment maps in an effects pipeline, or adding compute-style uniforms to a vertex/fragment shader consumed by ExoPlayer's GlProgram.
Related errors
- No call to setSamplerTexId() before bind.
- glError: {gluErrorString(error)}
- 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/339e220d316c5955.
Report an issue: GitHub.