{"record":{"id":"06af9722979cc1d7","repo":"google/ExoPlayer","slug":"attempting-to-open-a-session-using-a-dummy-exomedi","errorCode":null,"errorMessage":"Attempting to open a session using a dummy ExoMediaDrm.","messagePattern":"Attempting to open a session using a dummy ExoMediaDrm\\.","errorType":"exception","errorClass":"MediaDrmException","httpStatus":null,"severity":"error","filePath":"library/core/src/main/java/com/google/android/exoplayer2/drm/DummyExoMediaDrm.java","lineNumber":63,"sourceCode":"\n  @Override\n  public void setOnEventListener(@Nullable OnEventListener listener) {\n    // Do nothing.\n  }\n\n  @Override\n  public void setOnKeyStatusChangeListener(@Nullable OnKeyStatusChangeListener listener) {\n    // Do nothing.\n  }\n\n  @Override\n  public void setOnExpirationUpdateListener(@Nullable OnExpirationUpdateListener listener) {\n    // Do nothing.\n  }\n\n  @Override\n  public byte[] openSession() throws MediaDrmException {\n    throw new MediaDrmException(\"Attempting to open a session using a dummy ExoMediaDrm.\");\n  }\n\n  @Override\n  public void closeSession(byte[] sessionId) {\n    // Do nothing.\n  }\n\n  @Override\n  public KeyRequest getKeyRequest(\n      byte[] scope,\n      @Nullable List<DrmInitData.SchemeData> schemeDatas,\n      int keyType,\n      @Nullable HashMap<String, String> optionalParameters) {\n    // Should not be invoked. No session should exist.\n    throw new IllegalStateException();\n  }\n\n  @Override","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/core/src/main/java/com/google/android/exoplayer2/drm/DummyExoMediaDrm.java#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nMediaSource source = new DashMediaSource.Factory(dataSourceFactory)\n    .createMediaSource(dashUri); // DRM init data present, no DrmSessionManager -> dummy DRM path\n\n// after\nHttpDataSource.Factory httpFactory = new DefaultHttpDataSource.Factory();\nDrmSessionManager drm = new DefaultDrmSessionManager.Builder()\n    .setUuidAndExoMediaDrmProvider(C.WIDEVINE_UUID, FrameworkMediaDrm.DEFAULT_PROVIDER)\n    .build(new HttpMediaDrmCallback(LICENSE_URL, httpFactory));\nMediaSource source = new DashMediaSource.Factory(dataSourceFactory)\n    .setDrmSessionManagerProvider(unused -> drm)\n    .createMediaSource(dashUri);","handlingStrategy":"try-catch","validationCode":"UUID scheme = C.WIDEVINE_UUID;\nandroid.media.MediaDrm mediaDrm = null;\nboolean supported;\ntry {\n  supported = android.media.MediaDrm.isCryptoSchemeSupported(scheme);\n} finally { if (mediaDrm != null) mediaDrm.release(); }\nif (!supported) {\n  // do not start DRM playback on this device; show a clear message\n}","typeGuard":null,"tryCatchPattern":"// In Player.Listener / AnalyticsListener:\n@Override\npublic void onPlayerError(PlaybackException error) {\n  for (Throwable t = error; t != null; t = t.getCause()) {\n    if (t instanceof DrmSessionException\n        && t.getCause() instanceof android.media.NotProvisionedException == false\n        && t.getCause() instanceof MediaDrmException) {\n      String msg = t.getCause().getMessage();\n      if (msg != null && msg.contains(\"dummy ExoMediaDrm\")) {\n        // DRM was never really configured: fix session manager wiring\n      }\n    }\n  }\n}","preventionTips":["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."],"tags":["drm","exoplayer","android","widevine","playback","configuration"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}