pion/webrtc · error

incomplete frame header

Error message

incomplete frame header

What it means

Returned by IVFReader.ParseNextFrame when reading the 12-byte frame header ends with io.ErrUnexpectedEOF, i.e. the stream ended partway through a frame header. The IVF container stores a 12-byte header before every frame; a partial header means truncated or corrupt data.

Source

Thrown at pkg/media/ivfreader/ivfreader.go:22

// Package ivfreader implements IVF media container reader
package ivfreader

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
)

const (
	ivfFileHeaderSignature = "DKIF"
	ivfFileHeaderSize      = 32
	ivfFrameHeaderSize     = 12
)

var (
	errNilStream             = errors.New("stream is nil")
	errIncompleteFrameHeader = errors.New("incomplete frame header")
	errIncompleteFrameData   = errors.New("incomplete frame data")
	errIncompleteFileHeader  = errors.New("incomplete file header")
	errSignatureMismatch     = errors.New("IVF signature mismatch")
	errUnknownIVFVersion     = errors.New("IVF version unknown, parser may not parse correctly")
	errInvalidMediaTimebase  = errors.New("invalid media timebase")
)

// IVFFileHeader 32-byte header for IVF files
// https://wiki.multimedia.cx/index.php/IVF
type IVFFileHeader struct {
	signature           string // 0-3
	version             uint16 // 4-5
	headerSize          uint16 // 6-7
	FourCC              string // 8-11
	Width               uint16 // 12-13
	Height              uint16 // 14-15
	TimebaseDenominator uint32 // 16-19
	TimebaseNumerator   uint32 // 20-23

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Treat it as end-of-truncated-stream: stop iterating and validate/repair the source file.
  2. Re-download or re-capture the IVF file; verify integrity (checksum, duration).
  3. If partial frames are acceptable, catch this error specifically (errors.Is / equality) and break the loop instead of failing.

Example fix

// before
for {
    frame, _, err := reader.ParseNextFrame()
    if err != nil { return err }
}
// after
for {
    frame, _, err := reader.ParseNextFrame()
    if err != nil {
        if err == ivfreader.ErrIncompleteFrameHeader {
            log.Warn("truncated IVF file, stopping")
            break
        }
        return err
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

fi, err := f.Stat()
if err != nil {
    return err
}
if fi.Size() < 32 {
    return errors.New("file too small to contain an IVF frame")
}

Try / catch

frame, hdr, err := reader.ParseNextFrame()
if err == ivfreader.ErrIncompleteFrameHeader {
    log.Warn("IVF stream truncated in frame header; stopping")
    return nil
} else if err != nil {
    return err
}

Prevention

When it happens

Trigger: ParseNextFrame on a stream whose remaining bytes are between 1 and 11 when reading the frame header.

Common situations: Truncated downloads of IVF files, interrupted recordings, reading a file still being written, byte-range reads that cut a frame header in half.

Related errors


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