apache/beam · error
array len mismatch. decoding
Error message
array len mismatch. decoding %v but only have %v elements.
What it means
When decoding an array-typed element, the exec decoder reads an int32 element count from the wire and compares it to the target reflect type's length (c.t.Len()). If the encoded count differs from the fixed-length array type, decoding aborts with this error. It means the wire data doesn't match the declared Go array type.
Solutions
- Ensure the encoding and decoding sides use the identical fixed-size array type.
- If length is dynamic, switch the PCollection to a slice ([]T) instead of a fixed array.
- Re-generate or refresh stale data/checkpoints produced under a previous schema.
- Verify cross-language coder mappings agree on array size.
Example fix
// before
col := beam.Create(s, [3]int32{1, 2, 3}) // decoded elsewhere as [4]int32
// after
match sizes on both sides: [3]int32 encoded and [3]int32 decoded
// or use a slice:
col := beam.Create(s, []int32{1, 2, 3}) Defensive patterns
Strategy: type-guard
Type guard
// ensure the decode target matches the encoded fixed-size array
func arrayLenMatches(t reflect.Type, n int) bool {
return t.Kind() == reflect.Array && t.Len() == n
} Try / catch
if err := dec.DecodeTo(r, fv); err != nil {
if strings.Contains(err.Error(), "array len mismatch") {
return fmt.Errorf("wire data does not match declared array type %s: %w", c.t, err)
}
return err
} Prevention
- Never change fixed array sizes in a schema without draining/re-encoding in-flight data.
- Prefer slices over fixed-size arrays for variable-length data.
- Ensure cross-language counterparts declare the same array length.
- Version-check encoded blobs before decoding after a pipeline update.
When it happens
Trigger: arrayDecoder.DecodeTo reads n != c.t.Len() — e.g. decoding data written as a variable-length slice or from a different-size array type ([3]int32 vs [4]int32).
Common situations: Pipeline updates where an array's length changed between job versions; cross-language pipelines where the sender uses a dynamic-size type; stale checkpoints/snapshots with old schemas.
Related errors
- decodeStream value decode failed
- unable to decode array with iterable marker
- coder must not be nil
- coder type must be identical to node type
- could not unmarshal CoderRef from
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/968279a5dc93a157.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/exec/coder.go:807
// arrayDecoder reads the same format as iterableDecoder but
// produces arrays instead of slices, taking the encoded length
// as the length of the array.
type arrayDecoder struct {
t reflect.Type // array type
dec ElementDecoder
}
func (c *arrayDecoder) DecodeTo(r io.Reader, fv *FullValue) error {
// (1) Read count prefixed encoded data
size, err := coder.DecodeInt32(r)
if err != nil {
return err
}
n := int(size)
if n != c.t.Len() {
return errors.Errorf("array len mismatch. decoding %v but only have %v elements.", c.t, n)
}
switch {
case n >= 0:
rv := reflect.New(c.t).Elem()
var e FullValue
for i := 0; i < int(n); i++ {
err := c.dec.DecodeTo(r, &e)
if err != nil {
return err
}
if e.Elm != nil {
rv.Index(i).Set(reflect.ValueOf(e.Elm))
}
}
*fv = FullValue{Elm: rv.Interface()}
return nil
default:
return errors.Errorf("unable to decode array with iterable marker %v", n)View on GitHub (pinned to 12126d8942)