apache/beam · error
ReadSimpleRowHeader reading nils count: %v, %v
Error message
ReadSimpleRowHeader reading nils count: %v, %v
What it means
ReadSimpleRowHeader decodes a simple row header (field count and nils count) from a Beam row encoding stream. While reading the nils count varint it wraps any decode error in this message. It indicates the byte stream ended prematurely or is corrupted at the position where the nils count should be.
Source
Thrown at sdks/go/pkg/beam/core/graph/coder/row.go:222
}
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
- Verify the byte slice/stream is complete and not truncated before decoding (check you wrote/read the full encoded row).
- Ensure encoding and decoding use the same beam SDK version and coder (simple row header format changed across versions).
- Check that the reader is positioned at the start of a valid encoded row, not mid-record.
- Wrap Decode/Encode calls so partial failures invalidate the whole record instead of resuming mid-stream.
Example fix
// before: decoding a possibly truncated buffer
row, err := dec.Decode(bytes.NewReader(buf[:10]))
// after: validate buffer completeness first
if len(buf) < minHeaderBytes { return fmt.Errorf("buffer too short: %d", len(buf)) }
row, err := dec.Decode(bytes.NewReader(buf)) Defensive patterns
Strategy: try-catch
Validate before calling
if len(buf) < 2 { return fmt.Errorf("encoded row too short: %d bytes", len(buf)) } Type guard
func isTruncated(err error) bool { return errors.Is(err, io.EOF) || strings.Contains(err.Error(), "reading nils count") } Try / catch
row, err := dec.Decode(r)
if err != nil {
if isTruncated(err) { return ErrIncompleteRecord }
return err
} Prevention
- Always write the complete encoded row before attempting to decode
- Keep encoder/decoder Beam versions in sync
- Frame records with length prefixes when streaming rows
When it happens
Trigger: Calling ut1Dec / row decoding (e.g. via beam.RowEncoder or exec coders) on a truncated or misaligned byte stream: the field-count varint read succeeded, but the next DecodeVarInt call hit an error (typically io.EOF from a cut-off buffer).
Common situations: Truncated serialized rows from a corrupted data file or pipeline transport; decoding a hand-crafted or older-version byte encoding that lacks the nils count field; incorrect re-use of a decoder across stream boundaries.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- invalid float encoding for: %v
- ReadSimpleRowHeader expected no nils encoded count, got %v
- error decoding []byte field
- invalid varintz encoding for: %v
- invalid varuintz encoding for: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d70a78b85e7f690f.
Report an issue: GitHub.