google/ExoPlayer · critical · RuntimeException
Error instantiating VP9 extension
Error message
Error instantiating VP9 extension
What it means
DefaultRenderersFactory reflectively loads the optional VP9 extension renderer (com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer) when an extension renderer mode beyond OFF is set. ClassNotFoundException is treated as 'extension not built' and silently ignored, but any other reflective failure (NoSuchMethodException, IllegalAccessException, InvocationTargetException from a constructor crash) means the extension classes are on the classpath yet broken, so the factory aborts by wrapping the cause in a RuntimeException. This is a fail-fast guard: a half-present extension would otherwise cause subtle runtime decoder failures later.
Source
Thrown at library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java:407
clazz.getConstructor(
long.class,
android.os.Handler.class,
com.google.android.exoplayer2.video.VideoRendererEventListener.class,
int.class);
Renderer renderer =
(Renderer)
constructor.newInstance(
allowedVideoJoiningTimeMs,
eventHandler,
eventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded LibvpxVideoRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
// The extension is present, but instantiation failed.
throw new RuntimeException("Error instantiating VP9 extension", e);
}
try {
// Full class names used for constructor args so the LINT rule triggers if any of them move.
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer");
Constructor<?> constructor =
clazz.getConstructor(
long.class,
android.os.Handler.class,
com.google.android.exoplayer2.video.VideoRendererEventListener.class,
int.class);
Renderer renderer =
(Renderer)
constructor.newInstance(
allowedVideoJoiningTimeMs,
eventHandler,
eventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);View on GitHub (pinned to dd430f7053)
Solutions
- Check the chained cause in the RuntimeException (e.getCause()) — it names the real failure such as UnsatisfiedLinkError or NoSuchMethodException.
- Ensure the exoplayer-vp9 extension artifact version exactly matches the core library version.
- Keep ProGuard/R8 from obfuscating or removing extension classes and their constructor signatures (add keep rules for com.google.android.exoplayer2.ext.**).
- If you do not need VP9 software decoding, build with EXTENSION_RENDERER_MODE_OFF so the reflective block is skipped entirely.
Example fix
// before
DefaultRenderersFactory factory =
new DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON);
// after — only enable extensions when the matching extension build is packaged
DefaultRenderersFactory factory =
new DefaultRenderersFactory(context)
.setExtensionRendererMode(
BuildConfig.USE_VPX_EXTENSION
? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON
: DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF); Defensive patterns
Strategy: try-catch
Validate before calling
Class<?> clazz;
try {
clazz = Class.forName("com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer");
} catch (ClassNotFoundException e) {
clazz = null;
}
boolean vp9ExtensionLoadable = false;
if (clazz != null) {
try {
clazz.getConstructor(long.class, Handler.class,
VideoRendererEventListener.class, int.class);
vp9ExtensionLoadable = true;
} catch (NoSuchMethodException ignored) {
}
}
int mode = vp9ExtensionLoadable
? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON
: DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF; Try / catch
try {
player = new ExoPlayer.Builder(vp9Factory).build(context);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("VP9 extension")) {
// extension present but broken: fall back to core renderers
player = new ExoPlayer.Builder(
new DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF))
.build(context);
} else { throw e; }
} Prevention
- Pin exoplayer-core and every extension artifact to the identical version
- Add R8 keep rules for com.google.android.exoplayer2.ext.** constructors
- Run a smoke playback test on every release build type (not just debug)
- Verify each target ABI has the extension .so in the final APK with the Bundletool APK analyzer
When it happens
Trigger: Building the player with DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON (or PREFER) while the vp9 extension AAR/module is on the classpath but its renderer constructor signature does not match the one looked up (long, Handler, VideoRendererEventListener, int), or the renderer constructor itself throws (e.g. its native libvpx library failed to load via System.loadLibrary).
Common situations: Mixing extension and core versions from different ExoPlayer releases (constructor args changed between versions); a ProGuard/R8 pass that renamed or stripped constructor parameter types; an APK built with a vp9 .so missing for the device ABI; reflective access blocked on newer JDK/Android (module restrictions).
Related errors
- Error instantiating AV1 extension
- Error instantiating MIDI extension
- Error instantiating Opus extension
- Error instantiating FLAC extension
- Error instantiating FFmpeg extension
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/1c27df655cc79caf.
Report an issue: GitHub.