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
- Verify the input is an Opus stream (payload begins with the 8 bytes 'OpusHead')
- Use the correct reader for other codecs (e.g. a Vorbis reader)
- 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
- Confirm codec (probe with ffprobe) before choosing the Ogg reader
- Do not hand-edit ID page bytes
- Route Vorbis/Speex streams to dedicated readers
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
- wrong header, expected beginning of stream
- bad opus tags signature
- payload for id page must be 19 bytes
- unsupported channel mapping family
- invalid channel count
AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03).
Data as JSON: /api/errors/285773c88a9994c5.
Report an issue: GitHub.