apache/beam · error
could not unmarshal KV coder from
Error message
could not unmarshal KV coder from %v, want exactly 2 components but have %d
What it means
When makeCoder encounters a KV coder URN, it expects exactly two component coders (key and value). If the coder proto lists a different number of components, unmarshaling fails with this error including the raw coder proto and the actual component count.
Solutions
- Inspect the printed coder proto in the error and ensure the KV coder declares exactly 2 component coder IDs.
- Fix the pipeline construction code so KV PCollections register both key and value coders.
- Regenerate the pipeline with a standard Beam SDK rather than hand-building coder protos.
- Check the producing runner/SDK for known bugs in coder serialization.
Defensive patterns
Strategy: validation
Validate before calling
if c := comps.GetCoders()[kvCoderID]; c != nil && len(c.GetComponentCoderIds()) != 2 {
return fmt.Errorf("KV coder %s must have 2 components, has %d", kvCoderID, len(c.GetComponentCoderIds()))
} Try / catch
cd, err := um.Coder(id)
if err != nil && strings.Contains(err.Error(), "want exactly 2 components") {
log.Printf("malformed KV coder proto: %v", err)
} Prevention
- Use the standard Beam SDK pipeline building code to emit KV coders.
- Validate coder component arity before submitting custom-built protos.
- Round-trip marshal/unmarshal in tests to catch malformed coders.
When it happens
Trigger: makeCoder processing beam:coders:kv:v1 with components != 2, typically from a malformed or hand-edited pipeline proto, or a runner emitting a KV coder with wrong component arity.
Common situations: Custom runners or foreign SDKs producing non-conformant KV coders; corrupted pipeline serialization; manual proto construction that forgot one KV component.
Related errors
- could not unmarshal kv coder value component
- could not unmarshal length prefix coder from
- could not unmarshal windowed value coder from
- failed to marshal KV coder
- ShardedKey coder requires exactly 1 component (key), got
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/3ccd179f8d6a11c4.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/coder.go:212
switch urn {
case urnBytesCoder:
return coder.NewBytes(), nil
case urnBoolCoder:
return coder.NewBool(), nil
case urnVarIntCoder:
return coder.NewVarInt(), nil
case urnDoubleCoder:
return coder.NewDouble(), nil
case urnStringCoder:
return coder.NewString(), nil
case urnKVCoder:
if len(components) != 2 {
return nil, errors.Errorf("could not unmarshal KV coder from %v, want exactly 2 components but have %d", c, len(components))
}
key, err := b.Coder(components[0])
if err != nil {
return nil, err
}
id := components[1]
elm, err := b.peek(id)
if err != nil {
return nil, errors.Errorf("could not unmarshal kv coder value component: %w", err)
}
switch elm.GetSpec().GetUrn() {
case urnIterableCoder, urnStateBackedIterableCoder:
iterElmID := elm.GetComponentCoderIds()[0]
// TODO(https://github.com/apache/beam/issues/18032): If CoGBK with > 1 input, handle as special GBK. We expectView on GitHub (pinned to 12126d8942)