apache/beam · error

ReadSimpleRowHeader expected no nils encoded count, got %v

Error message

ReadSimpleRowHeader expected no nils encoded count, got %v

What it means

After reading the nils count from a simple row header, ReadSimpleRowHeader requires it to be zero (simple rows encode no nils). A non-zero value means the stream was produced by a coder variant that encodes nils (e.g. the full/nils-aware header), not the simple one. The library rejects this to avoid mis-decoding.

Source

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

// 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. Encode and decode with the same coder type: if rows may contain nils, use the coder variant that supports nils on both sides.
  2. Regenerate the serialized data with the matching encoder rather than hand-editing encoded bytes.
  3. Check Beam SDK version parity between the producer and consumer of the encoded rows.
  4. Inspect the first bytes of the stream to confirm which header format was used before choosing a decoder.

Example fix

// before: reading nils-encoding data with the simple decoder
row, err := simpleDec.Decode(r)
// after: use the coder that matches how the data was encoded
row, err := nilsAwareDec.Decode(r)
Defensive patterns

Strategy: validation

Validate before calling

// Confirm coder type used at encode time matches the decoder; log coder ID on both sides before decode.

Type guard

func usesSimpleCoder(c beam.Coder) bool { return strings.Contains(fmt.Sprintf("%T", c), "Simple") }

Try / catch

row, err := dec.Decode(r)
if err != nil && strings.Contains(err.Error(), "expected no nils encoded count") {
    return ErrCoderMismatch
}

Prevention

When it happens

Trigger: Decoding a row whose header contains a non-zero nils count with the simple-header decoder path (ut1Dec or anonymous decoder in row decoding), i.e. the data was encoded with a nils-aware coder but read with the simple coder.

Common situations: Mixing coder types between encode and decode stages; data written by an older/newer Beam version with different header conventions; manually constructing or editing encoded rows.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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