{"record":{"id":"1323ee3a457630bd","repo":"google/ExoPlayer","slug":"decoder-query-error","errorCode":"DECODER_QUERY_ERROR","errorMessage":"Decoder init failed: [{errorCode}], {format}","messagePattern":"Decoder init failed: \\[(.+?)\\], (.+?)","errorType":"exception","errorClass":"MediaCodecRenderer.DecoderInitializationException","httpStatus":null,"severity":"error","filePath":"library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java","lineNumber":1018,"sourceCode":"    return false;\n  }\n\n  private void maybeInitCodecWithFallback(\n      @Nullable MediaCrypto crypto, boolean mediaCryptoRequiresSecureDecoder)\n      throws DecoderInitializationException {\n    if (availableCodecInfos == null) {\n      try {\n        List<MediaCodecInfo> allAvailableCodecInfos =\n            getAvailableCodecInfos(mediaCryptoRequiresSecureDecoder);\n        availableCodecInfos = new ArrayDeque<>();\n        if (enableDecoderFallback) {\n          availableCodecInfos.addAll(allAvailableCodecInfos);\n        } else if (!allAvailableCodecInfos.isEmpty()) {\n          availableCodecInfos.add(allAvailableCodecInfos.get(0));\n        }\n        preferredDecoderInitializationException = null;\n      } catch (DecoderQueryException e) {\n        throw new DecoderInitializationException(\n            inputFormat,\n            e,\n            mediaCryptoRequiresSecureDecoder,\n            DecoderInitializationException.DECODER_QUERY_ERROR);\n      }\n    }\n\n    if (availableCodecInfos.isEmpty()) {\n      throw new DecoderInitializationException(\n          inputFormat,\n          /* cause= */ null,\n          mediaCryptoRequiresSecureDecoder,\n          DecoderInitializationException.NO_SUITABLE_DECODER_ERROR);\n    }\n\n    MediaCodecInfo preferredCodecInfo = availableCodecInfos.peekFirst();\n    while (codec == null) {\n      MediaCodecInfo codecInfo = availableCodecInfos.peekFirst();","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java#L1000-L1036","documentation":"MediaCodecRenderer.getCodecInfos() queries the device codec list (MediaCodecUtil.getCodecInfos) to find decoders matching the input format; if that query itself fails, a DecoderQueryException is raised and wrapped in DecoderInitializationException with code DECODER_QUERY_ERROR. The failure is not 'no decoder exists' but 'the codec database could not be queried' — the original cause (chained via DecoderInitializationException.getCause) explains what broke, typically an OEM codec entry that crashed enumeration or a framework MediaCodecList error.","triggerScenarios":"Renderer initialization (onInputFormatChanged -> maybeInitCodec path) on devices where MediaCodecUtil's codec enumeration throws: malformed codec names/capabilities reported by the vendor, NoSuchMethodException/IllegalStateException while reflecting codec capabilities, or a transient MediaCodecList failure; happens for any MIME query (video/audio) right at stream start.","commonSituations":"Specific OEM Android builds with broken codec metadata (common on low-end/older devices and some smart-TV forks); Android version upgrades exposing new capability fields that old ExoPlayer versions cannot parse; crashes reported only on a narrow device matrix; content plays on most devices but fails on one model.","solutions":["Upgrade ExoPlayer (MediaCodecUtil enumeration robustness is improved across releases) — many DecoderQueryException classes of failure are fixed in newer versions.","Inspect the cause: catch DecoderInitializationException and log getCause() to identify the offending codec/vendor error before changing anything else.","Reproduce on the affected device and check for vendor system updates; a broken codec list is a firmware defect.","If the device is known-bad, route those users to a software-decoder route (FFmpeg extension MediaCodecAudio/VideoRenderer alternatives) or an alternative stream profile as a fallback."],"exampleFix":"// before\nplayer.addAnalyticsListener(new AnalyticsListener() {}); // no handling: crash surfaces as generic playback error\n\n// after\n@Override\npublic void onPlayerError(PlaybackException error) {\n  Throwable cause = error.getCause();\n  if (cause instanceof DecoderInitializationException\n      && ((DecoderInitializationException) cause).decoderName == null\n      && cause.getCause() instanceof DecoderQueryException) {\n    // codec enumeration failed on this device: report model + cause, switch fallback stream\n    logDecoderQueryFailure(Build.MODEL, cause.getCause());\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"@Override\npublic void onPlayerError(PlaybackException error) {\n  if (error.errorCode == PlaybackException.ERROR_CODE_DECODER_INIT_FAILED\n      && error.getCause() instanceof DecoderInitializationException) {\n    DecoderInitializationException die = (DecoderInitializationException) error.getCause();\n    if (die.getCause() instanceof DecoderQueryException) {\n      // codec enumeration failed on this device: log Build.MODEL + cause, offer fallback rendition\n    }\n  }\n}","preventionTips":["Keep ExoPlayer/Media3 current — codec-enumeration hardening lands regularly.","Collect decoderInitFailed analytics with device model + cause so broken OEM builds are detectable and blockable server-side.","Provide an audio-only or transcoded fallback rendition players can switch to on decoder failure.","Test on a real device matrix (especially low-end OEMs) before assuming codec queries never fail."],"tags":["exoplayer","android","media-codec","decoder","oem","initialization"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}