apache/beam · error
key coder for %v is %v, want %v
Error message
key coder for %v is %v, want %v
What it means
Error returned by NewCoGBK when two inputs to a CoGBK edge have different key coders: the key coder of a later input does not Equals the first input's key coder c. Even if key types agree structurally, the runner requires identical coders so keys hash/encode consistently across all joined collections.
Source
Thrown at sdks/go/pkg/beam/core/graph/edge.go:225
}
if !typex.IsKV(ns[0].Type()) {
return nil, addContext(errors.Errorf("input type must be KV: %v", ns[0]), s)
}
// (1) Create CoGBK result type: KV<T,U>, .., KV<T,Z> -> CoGBK<T,U,..,Z>.
c := ns[0].Coder.Components[0]
w := inputWindow(ns)
bounded := inputBounded(ns)
comp := []typex.FullType{c.T, ns[0].Type().Components()[1]}
for i := 1; i < len(ns); i++ {
n := ns[i]
if !typex.IsKV(n.Type()) {
return nil, addContext(errors.Errorf("input type must be KV: %v", n), s)
}
if !n.Coder.Components[0].Equals(c) {
return nil, addContext(errors.Errorf("key coder for %v is %v, want %v", n, n.Coder.Components[0], c), s)
}
if !w.Equals(n.WindowingStrategy()) {
return nil, addContext(errors.Errorf("mismatched CoGBK windowing strategies: %v, want %v", n.WindowingStrategy(), w), s)
}
if bounded != n.Bounded() {
return nil, addContext(errors.Errorf("unmatched CoGBK boundedness: %v, want %v", n.Bounded(), bounded), s)
}
comp = append(comp, n.Type().Components()[1])
}
t := typex.NewCoGBK(comp...)
out := g.NewNode(t, w, bounded)
// (2) Add CoGBK edge
edge := g.NewEdge(s)
edge.Op = CoGBKView on GitHub (pinned to 12126d8942)
Solutions
- Ensure all inputs derive their key coders from the same default coding of the key type
- Remove or uniformly apply custom key coders across all CoGBK inputs
- Explicitly set matching coders on the key side of each input
Example fix
// before beam.CoGroupByKey(s, a, beam.ParDo(s, customKeyedFn, b)) // custom key coder // after beam.CoGroupByKey(s, a, beam.ParDo(s, defaultKeyedFn, b))
Defensive patterns
Strategy: validation
Validate before calling
keyCoder := inputs[0].Coder.Components[0]
for i, c := range inputs[1:] {
if !c.Coder.Components[0].Equals(keyCoder) {
return fmt.Errorf("input %d key coder mismatch", i+1)
}
} Try / catch
if err := beam.TryCoGroupByKey(s, a, b); err != nil {
return fmt.Errorf("CoGroupByKey key coder mismatch: %w", err)
} Prevention
- Let all key PCollections use the default coder for the key type
- Apply custom key coders uniformly or not at all
- Pin Beam SDK versions across pipeline components
When it happens
Trigger: Inputs whose keys have the same Go type but different coders (e.g. one side uses a custom key coder variant, another the default), detected via Coder.Components[0].Equals.
Common situations: Applying a custom key coder on one PCollection but not another, or SDK version differences producing non-equal default coders for keys.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- failed to marshal CoGBK coder %v
- varint too long
- %v
- unable to rewrite coder %v for state %v for transform %v in
- unknown coder used for ordered list state after re-write id:
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a1ad32e29995b7a1.
Report an issue: GitHub.