pion/webrtc · error

bad payload signature

Error message

bad payload signature

What it means

errBadIDPagePayloadSignature is returned when the ID page payload does not start with the 'OpusHead' magic signature (HeaderOpusID). The error is wrapped with the actual signature found, e.g. "bad payload signature: expected OpusHead, got ...." This indicates the stream is not an Opus stream despite passing the page-type checks.

Source

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

	"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
// signature (the first page of an Opus stream in an Ogg container).
//
// Use OggPageHeader.OpusPacketType() to classify a page payload as OpusHead,

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Verify the input is an Opus stream (payload begins with the 8 bytes 'OpusHead')
  2. Use the correct reader for other codecs (e.g. a Vorbis reader)
  3. Check for corruption or off-by-N offsets when slicing the payload

Example fix

// before: feeding a vorbis ogg file to the opus reader
r, err := oggreader.NewWith(vorbisFile)
// after
if !bytes.HasPrefix(payload, []byte("OpusHead")) {
    return errors.New("not an opus stream")
}
r, err := oggreader.NewWith(opusFile)
Defensive patterns

Strategy: validation

Validate before calling

if !bytes.HasPrefix(payload, []byte("OpusHead")) {
    return fmt.Errorf("expected OpusHead, got %q", payload[:min(8, len(payload))])
}

Type guard

func isOpusHead(payload []byte) bool {
    return bytes.HasPrefix(payload, []byte("OpusHead"))
}

Try / catch

_, hdr, err := oggreader.NewWith(f)
if errors.Is(err, oggreader.ErrBadIDPagePayloadSignature) {
    // input is not an Opus stream; select another decoder
}

Prevention

When it happens

Trigger: validateOpusPageHeader (oggreader.go:217) reading an ID page whose payload signature differs from OpusHead; also asserted in oggreader_test.go:182 with a corrupted signature.

Common situations: Pointing the Opus reader at a Vorbis/Speex/other Ogg stream, byte corruption in transit, or writing a wrong magic value in a synthetic stream.

Related errors


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