pion/webrtc · error

data is not a H265/HEVC bitstream

Error message

data is not a H265/HEVC bitstream

What it means

Returned when the head of the stream does not contain a valid H265/HEVC Annex-B start-code prefix: fewer than 3 bytes read, or no 00 00 01 / 00 00 00 01 sequence found by bitStreamStartsWithH265Prefix. The reader rejects data that cannot be an HEVC bitstream before parsing.

Source

Thrown at pkg/media/h265reader/h265reader.go:26

	"bytes"
	"errors"
	"io"
)

// H265Reader reads data from stream and constructs h265 nal units.
type H265Reader struct {
	stream                      io.Reader
	nalBuffer                   []byte
	countOfConsecutiveZeroBytes int
	nalPrefixParsed             bool
	readBuffer                  []byte
	tmpReadBuf                  []byte
	includeSEI                  bool
}

var (
	errNilReader           = errors.New("stream is nil")
	errDataIsNotH265Stream = errors.New("data is not a H265/HEVC bitstream")
)

func (reader *H265Reader) shouldSkipNAL(naluType NalUnitType) bool {
	return !reader.includeSEI && (naluType == NalUnitTypePrefixSei || naluType == NalUnitTypeSuffixSei)
}

// NewReader creates new H265Reader.
func NewReader(in io.Reader) (*H265Reader, error) {
	if in == nil {
		return nil, errNilReader
	}

	reader := &H265Reader{
		stream:          in,
		nalBuffer:       make([]byte, 0),
		nalPrefixParsed: false,
		readBuffer:      make([]byte, 0),
		tmpReadBuf:      make([]byte, 4096),

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Confirm the input is HEVC Annex-B (begins with a start code) before parsing.
  2. If the source is H264, use h264reader; if containerized, convert to Annex-B first.
  3. Check the stream isn't empty or truncated.

Example fix

// before
rdr, _ := h265reader.NewReader(h264Stream) // wrong codec
// after
if !bytes.Contains(head[:4], []byte{0, 0, 1}) {
    return fmt.Errorf("input is not H265/HEVC Annex-B bitstream")
}
rdr, err := h265reader.NewReader(hevcStream)
Defensive patterns

Strategy: validation

Validate before calling

head := make([]byte, 4)
n, _ := io.ReadFull(stream, head)
if n < 4 || head[0] != 0 || head[1] != 0 || head[2] != 1 && head[2] != 0 {
    return errors.New("not an H265/HEVC Annex-B bitstream")
}
stream.Seek(0, io.SeekStart)

Try / catch

_, err := reader.NextNAL()
if err == errDataIsNotH265Stream {
    return fmt.Errorf("input is not H265/HEVC Annex-B: %w", err)
}

Prevention

When it happens

Trigger: First NextNAL/parse call on data lacking HEVC start codes, or a stream shorter than 3 bytes.

Common situations: Feeding H264 data to the H265 reader, raw NAL units without start codes, container formats (MP4/HVCC) that are length-prefixed rather than Annex-B, empty/truncated files.

Related errors


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