pion/webrtc · error

%w: payload too short for comment len %d

Error message

%w: payload too short for comment len %d

What it means

Returned by parseSingleUserComment when there are not enough bytes left in the payload to even read the 4-byte (u32Size) length prefix of the comment at the given index. This means the declared comment count promised more comments than the payload actually contains, so the OpusTags packet is truncated or corrupt.

Source

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

	pos := vendorEnd + u32Size
	userComments := make([]UserComment, userCommentCount)

	for i := range userComments {
		comment, nextPos, err := parseSingleUserComment(payload, pos, u32Size, i)
		if err != nil {
			return nil, err
		}
		userComments[i] = comment
		pos = nextPos
	}

	return userComments, nil
}

func parseSingleUserComment(payload []byte, pos, u32Size, index int) (UserComment, int, error) {
	if pos+u32Size > len(payload) {
		return UserComment{}, 0, fmt.Errorf("%w: payload too short for comment len %d", errBadOpusTagsSignature, index)
	}

	commentLen32 := binary.LittleEndian.Uint32(payload[pos : pos+u32Size])
	pos += u32Size

	commentLen := int(commentLen32)
	if commentLen < 0 || pos+commentLen > len(payload) {
		return UserComment{}, 0, fmt.Errorf("%w: payload too short for comment %d", errBadOpusTagsSignature, index)
	}

	comment := string(payload[pos : pos+commentLen])
	pos += commentLen

	parts := strings.SplitN(comment, "=", 2)
	if len(parts) != 2 {
		return UserComment{}, 0, fmt.Errorf("%w: invalid comment %d", errBadOpusTagsSignature, index)
	}

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Check the file is not truncated (compare against source size; re-download/re-copy the file).
  2. Re-encode or rewrite the OpusTags metadata with a reliable tool to fix the comment count.
  3. Handle the error via errors.Is(err, errBadOpusTagsSignature) and skip or quarantine the malformed file.
  4. If processing streams, ensure you feed the complete OpusTags packet, not a page fragment.

Example fix

// before: feeding partial page data
comments, err := ParseOpusTags(partialPageData)
// after: assemble the full OpusTags packet first
fullPacket := concatenateOggPages(opusTagsPacket)
comments, err := ParseOpusTags(fullPacket)
Defensive patterns

Strategy: validation

Validate before calling

func isCompleteOpusTagsPacket(packet []byte) bool {
    if len(packet) < 8 { return false }
    vendorLen := int(binary.LittleEndian.Uint32(packet[8:12]))
    return len(packet) >= 12+vendorLen+4 // magic + vendorLen + vendor + commentCount
}

Try / catch

comments, err := ParseOpusTags(packet)
if err != nil {
    if errors.Is(err, errBadOpusTagsSignature) {
        return nil, fmt.Errorf("truncated or corrupt OpusTags packet: %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Parsing an OpusTags payload where, after the vendor string and comment count, fewer than u32Size bytes remain at the current cursor while iterating over the declared number of comments.

Common situations: Truncated Ogg Opus files from interrupted transfers, corrupted metadata segments, packets cut off at page boundaries, or files written by buggy encoders that overstate the comment count.

Related errors


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