pion/webrtc · error

bad opus tags signature

Error message

bad opus tags signature

What it means

errBadOpusTagsSignature is returned when the OpusTags header (second Ogg page) does not carry the expected 8-byte 'OpusTags' header type, or when the payload is too short to contain it. It is wrapped with fmt.Errorf so extra context ('payload too short' or 'expected %q, got %q') accompanies the sentinel. It is produced by validateOpusTagsHeader and its helpers (parseVendorString, parseUserComments).

Source

Thrown at pkg/media/oggreader/oggreader.go:26

	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"strings"
)

const (
	pageHeaderTypeBeginningOfStream = 0x02
	pageHeaderSignature             = "OggS"

	idPageBasePayloadLength = 19
	pageHeaderLen           = 27
)

var (
	errNilStream                       = errors.New("stream is nil")
	errBadIDPageSignature              = errors.New("bad header signature")
	errBadOpusTagsSignature            = errors.New("bad opus tags signature")
	errBadIDPageType                   = errors.New("wrong header, expected beginning of stream")
	errBadIDPageLength                 = errors.New("payload for id page must be 19 bytes")
	errBadIDPagePayloadSignature       = errors.New("bad payload signature")
	errShortPageHeader                 = errors.New("not enough data for payload header")
	errChecksumMismatch                = errors.New("expected and actual checksum do not match")
	errUnsupportedChannelMappingFamily = errors.New("unsupported channel mapping family")
)

// OggReader is used to read Ogg files and return page payloads.
type OggReader struct {
	stream               io.Reader
	bytesReadSuccesfully int64
	checksumTable        *[256]uint32
	doChecksum           bool
}

// OggHeader contains Opus codec metadata parsed from an Opus ID page.
// This header is extracted from an Ogg page payload that starts with the OpusHead

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Verify page 2 payload begins with 'OpusTags' before parsing
  2. Check the muxer that produced the file emits the OpusTags header page after OpusHead
  3. Ensure the full page payload was read (short reads cause 'payload too short')
  4. Handle the wrapped sentinel with errors.Is so the contextual message is preserved while matching

Example fix

// before
if err := validateOpusTagsHeader(payload[:4], 8); err != nil { ... } // payload too short
// after
if len(payload) < 8 || HeaderType(payload[:8]) != HeaderOpusTags {
    return fmt.Errorf("not an OpusTags payload")
}
if err := validateOpusTagsHeader(payload, 8); err != nil { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

if len(payload) < 8 || HeaderType(payload[:8]) != HeaderOpusTags {
    return errors.New("second ogg page is not OpusTags")
}

Type guard

func isOpusTagsPayload(p []byte) bool {
    return len(p) >= 8 && HeaderType(p[:8]) == HeaderOpusTags
}

Try / catch

err := validateOpusTagsHeader(payload, minLen)
if err != nil {
    if errors.Is(err, oggreader.ErrBadOpusTagsSignature) { // sentinel as exported by the package
        return fmt.Errorf("malformed OpusTags header: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Parsing an Ogg stream whose second page payload is shorter than minHeaderLen; the first 8 bytes of the OpusTags payload are not HeaderOpusTags (e.g. 'OpusHead' repeated, or a corrupted page); calling validateOpusTagsHeader directly with malformed payload.

Common situations: Streams where pages were reordered or the metadata page was dropped, files muxed with a broken tool, manually truncated metadata pages, fuzzed/corrupt inputs in tests.

Related errors


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