apache/beam · error

ReadSimpleRowHeader field count: %v, %v

Error message

ReadSimpleRowHeader field count: %v, %v

What it means

ReadSimpleRowHeader decodes a simple row header (field count plus a 0-length nils field). This error wraps a failure of the first DecodeVarInt reading the field count; n is included (usually 0) along with the underlying read error. The stream ended early, contains corrupt bytes, or is not a simple row header at all.

Source

Thrown at sdks/go/pkg/beam/core/graph/coder/row.go:215

func WriteSimpleRowHeader(fields int, w io.Writer) error {
	if err := EncodeVarInt(int64(fields), w); err != nil {
		return err
	}
	// Never nils, so we write the 0 byte header.
	if err := EncodeVarInt(0, w); err != nil {
		return fmt.Errorf("WriteSimpleRowHeader a 0 length nils bit field: %v", err)
	}
	return nil
}

// ReadSimpleRowHeader is a convenience function to read Beam Schema Row Headers
// for values that do not have any nil fields. Reads and validates the number of
// fields total (returning an error for mismatches, and checks that there are
// no nils encoded as a bit field.
func ReadSimpleRowHeader(fields int, r io.Reader) error {
	n, err := DecodeVarInt(r)
	if err != nil {
		return fmt.Errorf("ReadSimpleRowHeader field count: %v, %v", n, err)
	}
	if int(n) != fields {
		return fmt.Errorf("ReadSimpleRowHeader field count mismatch, got %v, want %v", n, fields)
	}
	n, err = DecodeVarInt(r)
	if err != nil {
		return fmt.Errorf("ReadSimpleRowHeader reading nils count: %v, %v", n, err)
	}
	if n != 0 {
		return fmt.Errorf("ReadSimpleRowHeader expected no nils encoded count, got %v", n)
	}
	return nil
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check the wrapped read error: io.EOF means truncated/empty input — verify the data source is complete.
  2. Ensure the reader is positioned at the start of a row header (don't consume bytes beforehand).
  3. Re-generate or re-export the data if the file/stream is corrupt.
  4. Confirm the writer used WriteSimpleRowHeader so formats match.

Example fix

// before
data := truncatedBytes[:5]
coder.ReadSimpleRowHeader(3, bytes.NewReader(data)) // EOF
// after
if len(data) < 2 { return io.ErrUnexpectedEOF }
coder.ReadSimpleRowHeader(3, bytes.NewReader(fullBytes))
Defensive patterns

Strategy: validation

Validate before calling

if r == nil { return errors.New("nil reader") }
if b, ok := r.(*bytes.Reader); ok && b.Len() < 2 { return io.ErrUnexpectedEOF }

Try / catch

err := coder.ReadSimpleRowHeader(fields, r)
if err != nil && strings.Contains(err.Error(), "ReadSimpleRowHeader field count:") {
	if errors.Is(err, io.EOF) { return io.ErrUnexpectedEOF }
	return err
}

Prevention

When it happens

Trigger: Calling ReadSimpleRowHeader on an empty/exhausted reader, on truncated data, or on data whose leading bytes are not a valid varint.

Common situations: Reading a serialized row file that was truncated; decoding from a closed gRPC stream; accidental use of ReadSimpleRowHeader on data written with a different header format.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/855ad6909d1701c7. Report an issue: GitHub.