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).

Solutions

  1. Verify the input actually starts with the 'OggS' magic bytes before parsing
  2. Open the correct file / seek to offset 0 of the Ogg stream
  3. Check the caller that produced the byte slice for off-by-one or header-stripping bugs
  4. 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

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.

Appendix: 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)