pion/webrtc · error
%w: payload too short
Error message
%w: payload too short
What it means
validateOpusTagsHeader returns this error when the payload handed to oggreader.ParseOpusTags is shorter than the minimum required OpusTags header length. The parser must read at least the 8-byte 'OpusTags' magic plus the vendor length field, so a truncated buffer cannot possibly be a valid tags header. The sentinel errBadOpusTagsSignature is wrapped so callers can match with errors.Is.
Source
Thrown at pkg/media/oggreader/oggreader.go:413
vendor, vendorEnd, err := parseVendorString(payload, headerMagicLen, u32Size, minHeaderLen)
if err != nil {
return nil, err
}
userComments, err := parseUserComments(payload, vendorEnd, u32Size)
if err != nil {
return nil, err
}
return &OpusTags{
Vendor: vendor,
UserComments: userComments,
}, nil
}
func validateOpusTagsHeader(payload []byte, minHeaderLen int) error {
if len(payload) < minHeaderLen {
return fmt.Errorf("%w: payload too short", errBadOpusTagsSignature)
}
got := HeaderType(payload[:8])
if got != HeaderOpusTags {
return fmt.Errorf("%w: expected %q, got %q", errBadOpusTagsSignature, HeaderOpusTags, got)
}
return nil
}
func parseVendorString(payload []byte, headerMagicLen, u32Size, minHeaderLen int) (string, int, error) {
vendorLen32 := binary.LittleEndian.Uint32(payload[headerMagicLen : headerMagicLen+u32Size])
if int(vendorLen32) > len(payload)-minHeaderLen {
return "", 0, fmt.Errorf("%w: payload too short for vendor string", errBadOpusTagsSignature)
}
vendorLen := int(vendorLen32)
vendorStart := headerMagicLen + u32SizeView on GitHub (pinned to 8c25dc09fa)
Solutions
- Verify the packet is the real OpusTags packet (starts with 'OpusTags') and pass the complete payload, not a truncated slice.
- Check that the Ogg page was fully reassembled before parsing; handle logical-stream segmentation so payload length is not cut.
- Guard at the call site with len(payload) >= 12 and errors.Is(err, ErrBadOpusTagsSignature) to skip non-tags packets.
Example fix
// before
header, err := oggreader.ParseOpusTags(packet[:7]) // truncated slice
// after
if len(packet) >= 12 {
header, err = oggreader.ParseOpusTags(packet)
} Defensive patterns
Strategy: validation
Validate before calling
const minOpusTagsLen = 12 // "OpusTags" magic + 4-byte vendor length
if len(payload) >= minOpusTagsLen && string(payload[:8]) == "OpusTags" {
tags, err := oggreader.ParseOpusTags(payload)
} Type guard
func isPlausibleOpusTags(p []byte) bool {
return len(p) >= 12 && string(p[:8]) == "OpusTags"
} Try / catch
tags, err := oggreader.ParseOpusTags(payload)
if errors.Is(err, oggreader.ErrBadOpusTagsSignature) {
// treat packet as non-tags / truncated; skip or reassemble
} else if err != nil {
return err
} Prevention
- Fully reassemble Ogg logical-stream packets (concatenate all pages) before parsing.
- Check packet length (>= 12 bytes) and magic before calling ParseOpusTags.
- Validate downloads/stream captures for completeness (checksum, final Ogg page flag).
- Never parse fixed-size slices of a variable-length header.
When it happens
Trigger: Calling ParseOpusTags with a payload shorter than the minHeaderLen computed for it (e.g. fewer than ~12 bytes, magic + 4-byte vendor length); passing a packet slice cut short by a truncated Ogg page or an off-by-one range.
Common situations: Truncated/corrupt downloads of .opus files; slicing a reassembled Ogg stream incorrectly (dropping trailing bytes); parsing a comment header captured with a fixed-size buffer smaller than the actual header; treating a random packet (audio or ID header) as the tags packet.
Related errors
- %w: payload too short for vendor+comment count
- bad opus tags signature
- %w: ambisonics family type 3 is not supported
- %w: expected %q, got %q
- %w: payload too short for vendor string
AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03).
Data as JSON: /api/errors/acd96eabd17aa516.
Report an issue: GitHub.