{"record":{"id":"0336f91e56136924","repo":"google/ExoPlayer","slug":"invalid-output-channel-config-mode-s-for-s","errorCode":null,"errorMessage":"Invalid output channel config (mode=%s) for: %s","messagePattern":"Invalid output channel config \\(mode=(.+?)\\) for: (.+?)","errorType":"exception","errorClass":"AudioSink.ConfigurationException","httpStatus":null,"severity":"error","filePath":"library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java","lineNumber":731,"sourceCode":"            getAudioCapabilities().getEncodingAndChannelConfigForPassthrough(inputFormat);\n        if (encodingAndChannelConfig == null) {\n          throw new ConfigurationException(\n              \"Unable to configure passthrough for: \" + inputFormat, inputFormat);\n        }\n        outputEncoding = encodingAndChannelConfig.first;\n        outputChannelConfig = encodingAndChannelConfig.second;\n        // Passthrough only supports AudioTrack playback parameters, but we only enable it this was\n        // specifically requested by the app.\n        enableAudioTrackPlaybackParams = preferAudioTrackPlaybackParams;\n      }\n    }\n\n    if (outputEncoding == C.ENCODING_INVALID) {\n      throw new ConfigurationException(\n          \"Invalid output encoding (mode=\" + outputMode + \") for: \" + inputFormat, inputFormat);\n    }\n    if (outputChannelConfig == AudioFormat.CHANNEL_INVALID) {\n      throw new ConfigurationException(\n          \"Invalid output channel config (mode=\" + outputMode + \") for: \" + inputFormat,\n          inputFormat);\n    }\n    int bufferSize =\n        specifiedBufferSize != 0\n            ? specifiedBufferSize\n            : audioTrackBufferSizeProvider.getBufferSizeInBytes(\n                getAudioTrackMinBufferSize(outputSampleRate, outputChannelConfig, outputEncoding),\n                outputEncoding,\n                outputMode,\n                outputPcmFrameSize != C.LENGTH_UNSET ? outputPcmFrameSize : 1,\n                outputSampleRate,\n                inputFormat.bitrate,\n                enableAudioTrackPlaybackParams ? MAX_PLAYBACK_SPEED : DEFAULT_PLAYBACK_SPEED);\n\n    offloadDisabledUntilNextConfiguration = false;\n    Configuration pendingConfiguration =\n        new Configuration(","sourceCodeStart":713,"sourceCodeEnd":749,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java#L713-L749","documentation":"DefaultAudioSink validates the resolved AudioTrack channel configuration after picking an output mode. If outputChannelConfig is AudioFormat.CHANNEL_INVALID — the channel layout implied by the format (e.g. Util.getAudioTrackChannelConfig of the channel count) has no Android AudioFormat equivalent (channel counts Android cannot map, like some raw counts for compressed or unusual layouts) — ConfigurationException('Invalid output channel config (mode=...) for: <format>') is thrown.","triggerScenarios":"Playing a format whose channel count maps to CHANNEL_INVALID for the chosen mode — typically passthrough encodings whose channel layout must be derived from the bitstream, or unusual PCM channel counts — combined with offload/passthrough configuration.","commonSituations":"Offload enabled for codecs where Android requires a channel mask instead of a count; device firmware returning odd channel masks; streams mislabeling channelCount in their manifests/containers; mixing raw channel counts with AudioFormat.CHANNEL_OUT_* masks in custom sinks.","solutions":["Fall back to PCM decode mode for that format (disable offload/passthrough), where channel config derives safely from channel count.","Check Util.getAudioTrackChannelConfig(format.channelCount) != AudioFormat.CHANNEL_INVALID before enabling offload/passthrough for an item.","Catch ConfigurationException and retry with a DefaultAudioSink built with OFFLOAD_MODE_DISABLED and no passthrough.","Verify the manifest/container channelCount matches the actual stream (mis-declared 0 or negative counts cause this)."],"exampleFix":"// before\nif (shouldOffload) sinkBuilder.setOffloadMode(OFFLOAD_MODE_ENABLED_ALWAYS);\n\n// after — gate offload on a mappable channel configuration\nboolean channelOk = Util.getAudioTrackChannelConfig(format.channelCount)\n    != AudioFormat.CHANNEL_INVALID;\nsinkBuilder.setOffloadMode(\n    shouldOffload && channelOk\n        ? DefaultAudioSink.OFFLOAD_MODE_ENABLED_ALWAYS\n        : DefaultAudioSink.OFFLOAD_MODE_DISABLED);","handlingStrategy":"validation","validationCode":"boolean channelConfigValid =\n    Util.getAudioTrackChannelConfig(format.channelCount)\n        != AudioFormat.CHANNEL_INVALID;\nif (!channelConfigValid) {\n  // avoid offload/passthrough for this item; use PCM mode\n}","typeGuard":null,"tryCatchPattern":"try {\n  prepareWithMode(item, OFFLOAD);\n} catch (PlaybackException e) { // wraps ConfigurationException\n  prepareWithMode(item, PCM); // channel config unresolvable in offload\n}","preventionTips":["Validate channel-count-to-mask mapping before enabling offload/passthrough","Verify container metadata channelCount is sane (0/negative → fix content)","Keep a PCM fallback path for unusual layouts"],"tags":["exoplayer","audio","configuration","channels","offload","audiotrack"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}