apache/beam · error
bad coder kind
Error message
bad coder kind: %v
What it means
EncodeCoderRef switches on the coder's Kind to map it to a runner-side CoderRef type. The default branch is reached when the Kind value is not any known/encodable kind (e.g. K=0 zero-value coders or custom kinds the Dataflow encoder doesn't support), so it fails with 'bad coder kind'.
Solutions
- Print/log c.Kind to identify the unsupported kind and ensure the coder is initialized through a supported constructor.
- Register a supported coder (custom coder via beam.Encoder/Decoder registration) for the offending type instead of relying on inference.
- Check that no zero-value coder.Coder is being passed (uninitialized struct).
- Upgrade/downgrade the Beam Go SDK so encode and decode support the same coder kinds.
Example fix
// before var c coder.Coder // Kind: "" (zero value) ref, err := graphx.EncodeCoderRef(&c) // after c := coder.NewString() // supported kind ref, err := graphx.EncodeCoderRef(c)
Defensive patterns
Strategy: try-catch
Validate before calling
func kindEncodable(k coder.Kind) bool {
switch k {
case coder.Bytes, coder.Bool, coder.VarInt, coder.Double, coder.String,
coder.KV, coder.CoGBK, coder.Iterable, coder.WindowedValue, coder.Nullable, coder.Row:
return true
}
return false
} Type guard
func isKnownKind(c *coder.Coder) bool { return c != nil && c.Kind != 0 && kindEncodable(c.Kind) } Try / catch
ref, err := graphx.EncodeCoderRef(c)
if err != nil {
var unsupported = errors.New("coder kind not encodable for this runner")
if strings.Contains(err.Error(), "bad coder kind") {
return fmt.Errorf("%w (kind=%v): register a supported coder for this type", unsupported, c.Kind)
}
return err
} Prevention
- Never pass zero-value coder.Coder structs
- Register custom encoders via beam.CustomCoder for unsupported types
- Keep the SDK version uniform across all pipeline tooling
When it happens
Trigger: Encoding a coder.Coder whose Kind is unrecognized by graphx: a zero-value Coder{}, a custom coder kind defined outside the core package, or a kind added in a newer Beam version than the one doing the encoding.
Common situations: Passing an uninitialized Coder struct; custom DoFns emitting values whose inferred coder kind isn't supported for the Dataflow runner; SDK version skew where a coder kind exists at decode time but not at encode time; row-encoder-requiring custom types lacking a registered coder.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- bad decoding function
- bad encoding function
- bad window kind
- could not unmarshal coder from
- custom coders must be length prefixed: %+v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cb41af21bde14741.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/dataflow.go:215
Components: []*CoderRef{{Type: stringType, PipelineProtoCoderID: c.ID}},
}, nil
case coder.Row:
schm, err := schema.FromType(c.T.Type())
if err != nil {
return nil, err
}
data, err := protox.EncodeBase64(schm)
if err != nil {
return nil, err
}
return &CoderRef{
Type: rowType,
Components: []*CoderRef{{Type: data}},
}, nil
default:
return nil, errors.Errorf("bad coder kind: %v", c.Kind)
}
}
// DecodeCoderRefs extracts usable coders from the encoded runner form.
func DecodeCoderRefs(list []*CoderRef) ([]*coder.Coder, error) {
var ret []*coder.Coder
for _, ref := range list {
c, err := DecodeCoderRef(ref)
if err != nil {
return nil, err
}
ret = append(ret, c)
}
return ret, nil
}
// DecodeCoderRef extracts a usable coder from the encoded runner form.
func DecodeCoderRef(c *CoderRef) (*coder.Coder, error) {View on GitHub (pinned to 12126d8942)