google/ExoPlayer · error · MediaDrmException
Attempting to open a session using a dummy ExoMediaDrm.
Error message
Attempting to open a session using a dummy ExoMediaDrm.
What it means
DummyExoMediaDrm is a no-op ExoMediaDrm stand-in that ExoPlayer installs when no real DRM backend is available or configured; every DRM operation is a no-op except openSession(), which throws by design. The throw means the pipeline attempted real DRM key acquisition (a session was requested for protected content) while running against this placeholder, i.e. protected content reached a player built without a usable DRM scheme. It surfaces to the app wrapped in a DrmSessionException / ExoPlaybackException renderer error.
Source
Thrown at library/core/src/main/java/com/google/android/exoplayer2/drm/DummyExoMediaDrm.java:63
@Override
public void setOnEventListener(@Nullable OnEventListener listener) {
// Do nothing.
}
@Override
public void setOnKeyStatusChangeListener(@Nullable OnKeyStatusChangeListener listener) {
// Do nothing.
}
@Override
public void setOnExpirationUpdateListener(@Nullable OnExpirationUpdateListener listener) {
// Do nothing.
}
@Override
public byte[] openSession() throws MediaDrmException {
throw new MediaDrmException("Attempting to open a session using a dummy ExoMediaDrm.");
}
@Override
public void closeSession(byte[] sessionId) {
// Do nothing.
}
@Override
public KeyRequest getKeyRequest(
byte[] scope,
@Nullable List<DrmInitData.SchemeData> schemeDatas,
int keyType,
@Nullable HashMap<String, String> optionalParameters) {
// Should not be invoked. No session should exist.
throw new IllegalStateException();
}
@OverrideView on GitHub (pinned to dd430f7053)
Solutions
- Configure a real DRM session manager: DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(C.WIDEVINE_UUID, FrameworkMediaDrm.DEFAULT_PROVIDER).build() with an HttpMediaDrmCallback license server, and pass it into the MediaSource factory.
- Verify the scheme is supported on the device before playback: android.media.MediaDrm.isCryptoSchemeSupported(uuid) (or FrameworkMediaDrm.isCryptoSchemeSupported) and fail gracefully with a clear message instead of a renderer error.
- Confirm the MediaSource was actually built with the DrmSessionManager (DashMediaSource.Factory.setDrmSourceManager / DefaultMediaSourceFactory.setDrmSessionManagerProvider) rather than the default.
- If the device genuinely lacks the scheme, switch to a supported scheme or serve aClear/transcoded variant for such devices.
Example fix
// before
MediaSource source = new DashMediaSource.Factory(dataSourceFactory)
.createMediaSource(dashUri); // DRM init data present, no DrmSessionManager -> dummy DRM path
// after
HttpDataSource.Factory httpFactory = new DefaultHttpDataSource.Factory();
DrmSessionManager drm = new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(C.WIDEVINE_UUID, FrameworkMediaDrm.DEFAULT_PROVIDER)
.build(new HttpMediaDrmCallback(LICENSE_URL, httpFactory));
MediaSource source = new DashMediaSource.Factory(dataSourceFactory)
.setDrmSessionManagerProvider(unused -> drm)
.createMediaSource(dashUri); Defensive patterns
Strategy: try-catch
Validate before calling
UUID scheme = C.WIDEVINE_UUID;
android.media.MediaDrm mediaDrm = null;
boolean supported;
try {
supported = android.media.MediaDrm.isCryptoSchemeSupported(scheme);
} finally { if (mediaDrm != null) mediaDrm.release(); }
if (!supported) {
// do not start DRM playback on this device; show a clear message
} Try / catch
// In Player.Listener / AnalyticsListener:
@Override
public void onPlayerError(PlaybackException error) {
for (Throwable t = error; t != null; t = t.getCause()) {
if (t instanceof DrmSessionException
&& t.getCause() instanceof android.media.NotProvisionedException == false
&& t.getCause() instanceof MediaDrmException) {
String msg = t.getCause().getMessage();
if (msg != null && msg.contains("dummy ExoMediaDrm")) {
// DRM was never really configured: fix session manager wiring
}
}
}
} Prevention
- Always pass an explicitly built DefaultDrmSessionManager to the MediaSource factory for DRM content; never rely on defaults.
- Gate DRM playback on android.media.MediaDrm.isCryptoSchemeSupported(uuid) plus a Widevine security-level check (MediaDrm.getPropertyString('securityLevel')).
- In CI/release checks, assert that protected sample URLs fail fast with a DRM configuration error rather than the dummy-DRM message — seeing it means wiring, not content.
- Emulators rarely ship Widevine: test DRM paths on real devices or use clear test assets.
When it happens
Trigger: Playing media whose DrmInitData declares a protection scheme through a DefaultDrmSessionManager whose ExoMediaDrm is the dummy instance (no FrameworkMediaDrm was created for the scheme); building a MediaSource with DrmSessionManager.DRM_SESSION_NOT_PLAYING/DUMMY-style manager and then feeding encrypted samples; DRM init failed earlier (e.g. FrameworkMediaDrm.newInstance could not be built for the UUID) and the session manager degraded to the dummy; onSetKeys/initiation of any DefaultDrmSession whose exoMediaDrm.openSession() is invoked on DummyExoMediaDrm.
Common situations: App plays DRM content on a device/emulator without the scheme (e.g. Widevine content on an emulator lacking Widevine DRM); DRM configuration lost during refactor (DrmSessionManager not passed to MediaSource factory); using ClearKey UUID on devices without ClearKey support; assuming all devices support the chosen scheme; testing protected streams in local/unit environments where no MediaDrm exists.
Related errors
- No license URL
- NO_SUITABLE_DECODER_ERROR
- Vpx decoder does not support secure decode.
- No mixing matrix for input channel count {audioFormat}
- Unhandled input format:
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/06af9722979cc1d7.
Report an issue: GitHub.