DrKLO/Telegram · error · OpusDecoderException
Invalid header, missing stream map
Error message
Invalid header, missing stream map
What it means
Channel mapping family 0 (headerBytes[18] == 0) is the default mono/stereo layout and only supports 1 or 2 channels. The decoder takes the default-mapping branch only for <= 2 channels; if the header declares family 0 but channelCount > 2 it is internally inconsistent and rejected as missing a stream map.
Source
Thrown at TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java:119
skipSamples = preSkipSamples;
byte[] headerBytes = initializationData.get(0);
if (headerBytes.length < 19) {
throw new OpusDecoderException("Invalid header length");
}
channelCount = getChannelCount(headerBytes);
if (channelCount > 8) {
throw new OpusDecoderException("Invalid channel count: " + channelCount);
}
int gain = readSignedLittleEndian16(headerBytes, 16);
byte[] streamMap = new byte[8];
int numStreams;
int numCoupled;
if (headerBytes[18] == 0) { // Channel mapping
// If there is no channel mapping, use the defaults.
if (channelCount > 2) { // Maximum channel count with default layout.
throw new OpusDecoderException("Invalid header, missing stream map");
}
numStreams = 1;
numCoupled = (channelCount == 2) ? 1 : 0;
streamMap[0] = 0;
streamMap[1] = 1;
} else {
if (headerBytes.length < 21 + channelCount) {
throw new OpusDecoderException("Invalid header length");
}
// Read the channel mapping.
numStreams = headerBytes[19] & 0xFF;
numCoupled = headerBytes[20] & 0xFF;
System.arraycopy(headerBytes, 21, streamMap, 0, channelCount);
}
nativeDecoderContext =
opusInit(SAMPLE_RATE, channelCount, numStreams, numCoupled, gain, streamMap);
if (nativeDecoderContext == 0) {
throw new OpusDecoderException("Failed to initialize decoder");View on GitHub (pinned to 45ab8f4308)
Solutions
- Use a properly mapped multichannel Opus stream (channel mapping family 1, which carries an explicit stream map).
- For mono/stereo content, keep channelCount <= 2 with mapping family 0.
Defensive patterns
Strategy: validation
Validate before calling
byte[] header = format.initializationData.get(0);
int mappingFamily = header[18] & 0xFF;
int ch = header[9] & 0xFF;
if (mappingFamily == 0 && ch > 2) {
throw new IllegalArgumentException(
"Opus mapping family 0 supports only mono/stereo, got " + ch + " channels");
}
new OpusDecoder(NUM_BUFFERS, NUM_BUFFERS, initSize, format.initializationData, cryptoConfig, outputFloat); Try / catch
try {
new OpusDecoder(..., format.initializationData, cryptoConfig, outputFloat);
} catch (OpusDecoderException e) {
if (e.getMessage().contains("missing stream map")) {
// use mapping family 1 content, or mono/stereo
} else { throw e; }
} Prevention
- For >2 channel Opus, use channel mapping family 1 (with an explicit stream map).
- Validate mapping-family/channel-count consistency before decoding.
When it happens
Trigger: An Opus identification header that sets channel mapping family to 0 while simultaneously reporting more than 2 channels - a malformed or hand-authored header.
Common situations: Corrupt Opus files; test fixtures with an inconsistent header; a muxer that wrote family 0 for multichannel audio by mistake.
Related errors
- Invalid initialization data size
- Invalid pre-skip or seek pre-roll
- Invalid header length
- Invalid channel count: {channelCount}
- Opus decoder does not support secure decode
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/08f3c4c1d0408eac.
Report an issue: GitHub.