pion/webrtc · error
bad header signature
Error message
bad header signature
What it means
errBadIDPageSignature is returned when the first Ogg page header does not begin with the required 4-byte 'OggS' capture signature. The reader validates the ID page header via validateOpusPageHeader and rejects anything that is not a valid Ogg stream start. It means the input is not a well-formed Ogg file (or the stream is misaligned).
Source
Thrown at pkg/media/oggreader/oggreader.go:25
import (
"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.View on GitHub (pinned to 8c25dc09fa)
Solutions
- Verify the input actually starts with the 'OggS' magic bytes before parsing
- Open the correct file / seek to offset 0 of the Ogg stream
- Check the caller that produced the byte slice for off-by-one or header-stripping bugs
- Use a tool (ogginfo) to confirm the file integrity; regenerate if corrupt
Example fix
// before
f, _ := os.Open("audio.opus") // actually raw opus, no ogg container
_, _, err := oggreader.NewWith(f) // errBadIDPageSignature
// after
// mux raw opus into an ogg container first, then:
f, _ := os.Open("audio.ogg")
_, _, err := oggreader.NewWith(f) Defensive patterns
Strategy: validation
Validate before calling
sig := make([]byte, 4)
if _, err := io.ReadFull(f, sig); err != nil || string(sig) != "OggS" {
return errors.New("input is not an Ogg stream")
}
// rewind, then: oggreader.NewWith(io.MultiReader(bytes.NewReader(sig), f)) Type guard
func isOggStream(b []byte) bool { return len(b) >= 4 && string(b[:4]) == "OggS" } Try / catch
_, _, err := oggreader.NewWith(f)
if err != nil {
if errors.Is(err, oggreader.ErrBadIDPageSignature) { // sentinel as exported by the package
return fmt.Errorf("not a valid Ogg file: %w", err)
}
return err
} Prevention
- Confirm the 'OggS' magic before handing a file to the reader
- Seek to byte 0 of the Ogg stream before parsing
- Do not strip container headers before demuxing
- Validate downloaded/moved files for integrity (checksum) before parsing
When it happens
Trigger: Passing a non-Ogg file (raw Opus, WAV, MP3) to oggreader; reading a stream offset from byte 0 (e.g. after seeking); a truncated/corrupt file whose first bytes were overwritten.
Common situations: Wrong file extension vs actual content, concatenated or partially downloaded files, reading from the middle of a container, test fixtures with intentionally corrupted headers.
Related errors
AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03).
Data as JSON: /api/errors/3115349faeecbf25.
Report an issue: GitHub.