apache/beam · error
unexpected coder kind
Error message
unexpected coder kind: %v
What it means
Produced by CoderMarshaller.Add's default branch when the coder's Kind matches none of the handled cases (Custom, KV, Window, Timer, Iterable, Bool, Bytes, etc.). It signals an unsupported or unrecognized coder kind in the model marshalling switch, then wrapped with 'failed to marshal coder' context.
Solutions
- Print/log c.Kind to identify the unsupported kind value.
- Upgrade the Go Beam SDK so the marshaller recognizes the coder kind.
- Replace the coder with a supported built-in (bytes, KV, iterable, windowed).
- If custom, use coder.NewCustomCoder with valid Encode/Decode functions, which takes the Custom branch instead.
- Check for version mismatch between pipeline-construction SDK and the Go container/runner.
Example fix
// before
c := &coder.Coder{Kind: coder.Kind(999), T: typex.New(typex.VarIntType)}
// after
c := coder.NewI( /* int64 element */ ) // use a known constructor so Kind is valid Defensive patterns
Strategy: type-guard
Validate before calling
switch c.Kind {
case coder.Custom, coder.KV, coder.Window, coder.Timer, coder.Iterable, coder.Bool, coder.Bytes:
// ok
default:
return fmt.Errorf("kind %v not marshalable", c.Kind)
} Type guard
func hasMarshalableKind(c *coder.Coder) bool {
k := c.Kind
return k == coder.Custom || k == coder.KV || k == coder.Window || k == coder.Timer || k == coder.Iterable || k == coder.Bool || k == coder.Bytes
} Try / catch
id, err := b.Add(c)
if err != nil && strings.Contains(err.Error(), "unexpected coder kind") {
return "", fmt.Errorf("coder %v uses unsupported kind %v; upgrade SDK or replace coder", c, c.Kind)
} Prevention
- Always build coders via exported constructors, never struct literals with raw Kind values.
- Pin matching Beam versions across all pipeline SDKs.
- Keep custom coders on the coder.Custom path with registered Encode/Decode.
When it happens
Trigger: Add/AddMulti receives a *coder.Coder whose Kind is not implemented by the marshaller — typically a hand-constructed coder or one produced by a newer/other SDK with a kind this Go version does not know.
Common situations: Version skew between Beam SDKs in cross-language pipelines; custom coders registered in one SDK but not Go; building coder.Coder values manually with an invalid zero-value Kind.
Related errors
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/c257abf9148a02ee.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/coder.go:582
comp = append(comp, ids...)
id, err := b.AddWindowCoder(c.Window)
if err != nil {
return "", errors.Wrapf(err, "failed to marshal window coder %v", c)
}
comp = append(comp, id)
return b.internBuiltInCoder(urnTimerCoder, comp...), nil
case coder.Iterable:
comp, err := b.AddMulti(c.Components)
if err != nil {
return "", errors.Wrapf(err, "failed to marshal iterable coder %v", c)
}
return b.internBuiltInCoder(urnIterableCoder, comp...), nil
default:
err := errors.Errorf("unexpected coder kind: %v", c.Kind)
return "", errors.WithContextf(err, "failed to marshal coder %v", c)
}
}
// AddMulti adds the given coders to the set and returns their ids. Idempotent.
func (b *CoderMarshaller) AddMulti(list []*coder.Coder) ([]string, error) {
var ids []string
for _, c := range list {
if id, err := b.Add(c); err != nil {
return nil, errors.Wrapf(err, "failed to marshal the coder %v.", c)
} else {
ids = append(ids, id)
}
}
return ids, nil
}
// AddWindowCoder adds a window coder.View on GitHub (pinned to 12126d8942)