pion/webrtc · error

%w: header is too long

Error message

%w: header is too long

What it means

The Opus comment header (signature 'OpusTags' + vendor length + vendor string + comment count) must fit within the configured maximum header length, typically one Ogg page. validateOpusTagsHeaderLen computes the base header length and returns this wrapped errInvalidOpusTags when the vendor string alone makes it exceed maxHeaderLen.

Source

Thrown at pkg/media/oggwriter/oggwriter.go:781

func validateOpusTagsWithMaxHeaderLen(opusTags OpusTags, maxHeaderLen uint64) error {
	if err := validateOpusTagString("vendor", opusTags.Vendor); err != nil {
		return err
	}
	if uint64(len(opusTags.UserComments)) > maxUint32Length {
		return fmt.Errorf("%w: too many user comments", errInvalidOpusTags)
	}

	if err := validateUserComments(opusTags.UserComments); err != nil {
		return err
	}

	return validateOpusTagsHeaderLen(opusTags, maxHeaderLen)
}

func validateOpusTagsHeaderLen(opusTags OpusTags, maxHeaderLen uint64) error {
	headerLen := uint64(len(commentPageSignature)) + 4 + uint64(len(opusTags.Vendor)) + 4
	if headerLen > maxHeaderLen {
		return fmt.Errorf("%w: header is too long", errInvalidOpusTags)
	}

	for _, comment := range opusTags.UserComments {
		userCommentLen := uint64(len(comment.Comment)) + 1 + uint64(len(comment.Value))
		commentFieldLen := 4 + userCommentLen
		if commentFieldLen > maxHeaderLen-headerLen {
			return fmt.Errorf("%w: header is too long", errInvalidOpusTags)
		}
		headerLen += commentFieldLen
	}

	return nil
}

func validateUserComments(comments []UserComment) error {
	for _, comment := range comments {
		if err := validateUserComment(comment); err != nil {
			return err

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Shorten the vendor string to fit (keep it well under ~65000 bytes).
  2. Raise the maxHeaderLen parameter if your pipeline allows larger headers.
  3. Drop or truncate the vendor to the default (defaultOpusTags uses a short defaultVendor).
  4. Precompute headerLen = 8+4+len(vendor)+4 and assert it <= maxHeaderLen before calling the writer.

Example fix

// before
tags.Vendor = strings.Repeat("x", 100000)
// after
tags.Vendor = "myapp v1.2" // short vendor fits in one page
Defensive patterns

Strategy: validation

Validate before calling

headerLen := uint64(8 + 4 + len(tags.Vendor) + 4)
if headerLen > maxHeaderLen { return errors.New("vendor string too long for header") }

Try / catch

if err := writer.SetOpusTags(tags); err != nil {
    if errors.Is(err, errInvalidOpusTags) && strings.Contains(err.Error(), "header is too long") {
        tags.Vendor = shortVendor; /* retry */
    }
    return err
}

Prevention

When it happens

Trigger: Setting a very long Vendor string on OpusTags (or via the vendor-setting API) so that len('OpusTags')+4+vendor+4 exceeds maxHeaderLen before any comments are considered.

Common situations: Using a long marketing/version string as the vendor tag; libraries that copy vendor strings from decoded input files into new recordings; a small maxHeaderLen (single Ogg page ≈ 65KB) combined with verbose vendor text.

Related errors


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