pion/webrtc · error

invalid channel count

Error message

invalid channel count

What it means

errInvalidChannelCount is returned when parsing or validating Opus channel mapping data for multichannel streams: the mapping table is empty, longer than math.MaxUint8, or the stream count is not 1 where required. The library only supports channel configurations whose stream/coupled counts match a valid Opus channel mapping.

Source

Thrown at pkg/media/oggwriter/oggwriter.go:56

	commentPageSignature               = "OpusTags"
	defaultVendor                      = "pion"
	pageHeaderSignature                = "OggS"
	pageHeaderSize                     = 27
	maxOggPageSegments                 = 255
	noGranulePosition                  = ^uint64(0)
	maxUint32Length                    = uint64(1<<32 - 1)
)

var (
	errFileNotOpened        = errors.New("file not opened")
	errOutputNotOpened      = errors.New("output not opened")
	errInvalidNilPacket     = errors.New("invalid nil packet")
	errDuplicateTrackSSRC   = errors.New("duplicate Ogg track SSRC")
	errDuplicateTrackSerial = errors.New("duplicate Ogg track serial")
	errTracksStarted        = errors.New("cannot add Ogg tracks after writing has started")
	errPacketSSRCMismatch   = errors.New("RTP packet SSRC does not match Ogg track SSRC")
	errInvalidOpusPacket    = errors.New("invalid Opus packet")
	errInvalidChannelCount  = errors.New("invalid channel count")
	errInvalidChannelMap    = errors.New("invalid channel mapping")
	errInvalidOpusTags      = errors.New("invalid OpusTags")
)

type pageRewriter interface {
	io.Seeker
	io.WriterAt
}

type writerConfig struct {
	sampleRate     uint32
	channelMapping channelMapping
	pageRewriter   pageRewriter
	opusTags       OpusTags
}

type trackConfig struct {
	sampleRate        uint32

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Use a supported channel count (mono or stereo, or a supported multichannel mapping)
  2. Ensure the OpusHead stream/coupled counts match the channel count and mapping table
  3. Verify the mapping table length is between 1 and 255 bytes
  4. Check upstream demuxing — the ident header may be corrupt

Example fix

// before
// channels = 3 with mapping family 0 (invalid; family 0 implies <= 2 channels)
// after
// use channels = 2 with mapping family 0, or family 1 with a valid mapping table
Defensive patterns

Strategy: validation

Validate before calling

func validChannelSetup(channels int, mappingFamily byte, streams, coupled uint8, order []byte) bool {
    if channels <= 0 || channels > 255 || len(order) == 0 {
        return false
    }
    if mappingFamily == 0 && channels > 2 {
        return false
    }
    return int(streams+coupled) == channels
}

Try / catch

if err := validateChannelMappingLayout(streams, coupled, order); err != nil {
    if strings.Contains(err.Error(), "invalid channel count") {
        return nil, fmt.Errorf("unsupported channel setup: streams=%d coupled=%d", streams, coupled)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Building channelMapping from an unsupported channel count (default case of the switch); calling validateChannelMappingLayout with an empty mapping, a mapping longer than 255 bytes, or streamCount != 1.

Common situations: Configuring an Opus track with an exotic channel count (e.g. 7.1 with an unsupported mapping family); passing a malformed OpusHead/ident header from an upstream demuxer; hand-built Opus headers in tests with wrong stream/coupled counts.

Related errors


AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03). Data as JSON: /api/errors/ddc288019e3a06f2. Report an issue: GitHub.