apache/beam · error
bad length prefix: %+v
Error message
bad length prefix: %+v
What it means
DecodeCoderRef maps length-prefix-type refs (used for bytes/string coders wrapped by Dataflow) back to coders. Such a ref must contain exactly one component; another count means the encoded graph is malformed, so decoding fails with the ref in the message.
Solutions
- Regenerate the pipeline from source so length-prefix coders are re-encoded correctly.
- Verify SDK version parity between the tool that produced the graph and the one decoding it.
- Check any custom graph mutation passes for component-list edits on bytes/string coders.
- Inspect the printed CoderRef to confirm the malformed component count and locate its producer.
Example fix
// before
ref := &graphx.CoderRef{Type: graphx.LengthPrefix, Components: []*graphx.CoderRef{a, b}}
c, err := graphx.DecodeCoderRef(ref)
// after
ref := &graphx.CoderRef{Type: graphx.LengthPrefix, Components: []*graphx.CoderRef{innerRef}}
c, err := graphx.DecodeCoderRef(ref) Defensive patterns
Strategy: try-catch
Validate before calling
func validLengthPrefixRef(r *graphx.CoderRef) bool {
return r != nil && r.Type == graphx.LengthPrefix && len(r.Components) == 1
} Type guard
func isLengthPrefixRef(r *graphx.CoderRef) bool { return r != nil && r.Type == graphx.LengthPrefix && len(r.Components) == 1 } Try / catch
c, err := graphx.DecodeCoderRef(ref)
if err != nil {
if strings.Contains(err.Error(), "bad length prefix") {
return nil, fmt.Errorf("corrupt length-prefix coder ref %v: %w", ref, err)
}
return nil, err
} Prevention
- Ensure bytes/string coders are encoded by the same SDK that decodes them
- Avoid custom tools that duplicate coder components
- Validate pipeline protos against the expected schema before decoding
When it happens
Trigger: Decoding a CoderRef with Type lengthPrefixType whose Components has length != 1 — during deserialization of a pipeline graph or job description produced/corrupted outside the current encoder.
Common situations: Pipeline artifacts serialized by a different Beam version with a different length-prefix layout; custom graph rewriters duplicating components; truncated or manually edited proto/json pipelines.
Related errors
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/3839396def48b69f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/dataflow.go:300
t := typex.New(typex.KVType, key.T, value.T)
return &coder.Coder{Kind: coder.KV, T: t, Components: []*coder.Coder{key, value}}, nil
case nullableType:
if len(c.Components) != 1 {
return nil, errors.Errorf("bad nullable: %+v", c)
}
inner, err := DecodeCoderRef(c.Components[0])
if err != nil {
return nil, err
}
t := typex.New(typex.NullableType, inner.T)
return &coder.Coder{Kind: coder.Nullable, T: t, Components: []*coder.Coder{inner}}, nil
case lengthPrefixType:
if len(c.Components) != 1 {
return nil, errors.Errorf("bad length prefix: %+v", c)
}
subC := c.Components[0]
switch subC.Type {
case stringType: // Needs special handling if wrapped by dataflow.
return coder.NewString(), nil
default:
return decodeDataflowCustomCoder(subC.Type)
}
case intervalWindowType:
return coder.NewIntervalWindowCoder(), nil
case windowedValueType:
if len(c.Components) != 2 {
return nil, errors.Errorf("bad windowed value: %+v", c)
}
View on GitHub (pinned to 12126d8942)