google/ExoPlayer · critical · RuntimeException

Error instantiating FLAC extension

Error message

Error instantiating FLAC extension

What it means

DefaultRenderersFactory reflectively loads the optional FLAC decoder renderer (com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer) via its (Handler, AudioRendererEventListener, AudioSink) constructor when extension renderers are enabled. If the class is found but reflection fails (signature mismatch, access failure, or constructor exception), the factory throws a RuntimeException carrying the cause. ClassNotFoundException is the only tolerated outcome because it simply means the extension was not compiled in.

Solutions

  1. Inspect the chained cause for NoSuchMethodException vs UnsatisfiedLinkError.
  2. Use identical versions for exoplayer-core and exoplayer-flac.
  3. Keep extension classes intact under R8: -keep class com.google.android.exoplayer2.ext.flac.** { *; }.
  4. Drop the extension and let the platform FLAC decoder handle it (Android 3.1+/most devices), i.e. EXTENSION_RENDERER_MODE_OFF.

Example fix

// before
 implementation 'com.google.android.exoplayer:exoplayer:2.19.1'
 implementation 'com.google.android.exoplayer:exoplayer-flac:2.18.1' // version drift!

// after
 implementation 'com.google.android.exoplayer:exoplayer:2.19.1'
 implementation 'com.google.android.exoplayer:exoplayer-flac:2.19.1' // aligned
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  Class.forName("com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer")
      .getConstructor(Handler.class, AudioRendererEventListener.class, AudioSink.class);
  // extension structurally present
} catch (ClassNotFoundException e) {
  // not packaged — fine, platform FLAC will be used
} catch (NoSuchMethodException e) {
  // version drift — do not enable extension mode
}

Try / catch

try {
  player = new ExoPlayer.Builder(flacFactory).build(context);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("FLAC extension")) {
    player = new ExoPlayer.Builder(new DefaultRenderersFactory(context)).build(context);
  } else { throw e; }
}

Prevention

When it happens

Trigger: EXTENSION_RENDERER_MODE_ON/PREFER plus a packaged exoplayer-flac module whose constructor cannot be resolved or whose instantiation throws (missing libflac native library).

Common situations: Mismatched exoplayer-flac and exoplayer-core versions; obfuscated release builds breaking the reflective constructor lookup; APK splits or ABI filters excluding the FLAC native .so; duplicate flac extensions (e.g. both exoplayer-flac and a full exoplayer uber-jar).

Related errors


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/4e11e172ad69e3b0. Report an issue: GitHub.

Appendix: source

Thrown at library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java:526

    }

    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.flac.LibflacAudioRenderer");
      Constructor<?> constructor =
          clazz.getConstructor(
              android.os.Handler.class,
              com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
              com.google.android.exoplayer2.audio.AudioSink.class);
      Renderer renderer =
          (Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
      out.add(extensionRendererIndex++, renderer);
      Log.i(TAG, "Loaded LibflacAudioRenderer.");
    } 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 FLAC 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.ffmpeg.FfmpegAudioRenderer");
      Constructor<?> constructor =
          clazz.getConstructor(
              android.os.Handler.class,
              com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
              com.google.android.exoplayer2.audio.AudioSink.class);
      Renderer renderer =
          (Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
      out.add(extensionRendererIndex++, renderer);
      Log.i(TAG, "Loaded FfmpegAudioRenderer.");
    } catch (ClassNotFoundException e) {
      // Expected if the app was built without the extension.
    } catch (Exception e) {

View on GitHub (pinned to dd430f7053)