apache/beam · error
could not unmarshal coder from
Error message
could not unmarshal coder from %v, unknown URN %v
What it means
During pipeline deserialization, graphx.makeCoder saw a coder FunctionSpec whose URN is not among the known Beam coder URNs. This happens when the serialized pipeline contains a coder kind the Go SDK's CoderUnmarshaller does not recognize (unsupported coder kind, cross-language coder, or newer Beam coder URN). The unmarshal aborts and the pipeline fails to decode.
Solutions
- Upgrade the Go Beam SDK to the same or newer version that produced the pipeline so the URN is recognized
- Check which URN is printed in the error and confirm it is a supported coder kind in sdks/go/pkg/beam/core/runtime/graphx/coder.go
- If the pipeline uses a custom coder, ensure it was registered with beam.RegisterType on the Go side before deserialization
- Avoid mixing SDK versions between pipeline construction and deserialization/runner
Example fix
// before: decoding a pipeline built by a newer SDK with an unrecognized coder URN // after: upgrade the SDK // go.mod require github.com/apache/beam/sdks/v2 v2.xx.0 // bump to >= version that wrote the graph beam.Init() // then re-run pipeline decode
Defensive patterns
Strategy: try-catch
Validate before calling
// Before decoding, verify the producing SDK version matches your Go SDK // e.g. log the pipeline's beam_version and compare with sdk version
Try / catch
// err contains "unknown URN" -> log urn from message and check
// supported URNs in graphx before retrying with an upgraded SDK
if err != nil && strings.Contains(err.Error(), "unknown URN") {
// fail fast with a clear upgrade hint
} Prevention
- Keep the Go SDK version >= the version that serialized the pipeline
- Avoid hand-editing pipeline JSON/proto models
- Register all custom types before beam.Init
When it happens
Trigger: Deserializing a pipeline model (e.g. from a job submission or JSON/proto graph) whose coder spec has an unrecognized URN; unmarshalling a graph written by a newer Beam SDK or another SDK with coder kinds the Go runtime doesn't map.
Common situations: Cross-language pipeline portability (Python/Java writes a coder the Go SDK lacks); version skew where the runner serialized a coder URN introduced after the local Go SDK version; hand-edited or corrupted pipeline JSON.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- bad coder kind
- bad decoding function
- bad encoding function
- bad window kind
- custom coders must be length prefixed: %+v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d097afaf91975020.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/coder.go:407
return nil, err
}
return coder.NewSK(keyC), nil
case urnIntervalWindow:
return coder.NewIntervalWindowCoder(), nil
// Special handling for the global window coder so it can be treated as
// a general coder. Generally window coders are not used outside of
// specific contexts, but this enables improved testing.
// Window types are not permitted to be fulltypes, so
// we use assignably equivalent anonymous struct types.
case urnGlobalWindow:
w, err := b.WindowCoder(id)
if err != nil {
return nil, errors.Errorf("could not unmarshal global window coder: %w", err)
}
return &coder.Coder{Kind: coder.Window, T: typex.New(reflect.TypeOf((*struct{})(nil)).Elem()), Window: w}, nil
default:
return nil, errors.Errorf("could not unmarshal coder from %v, unknown URN %v", c, urn)
}
}
func (b *CoderUnmarshaller) peek(id string) (*pipepb.Coder, error) {
c, ok := b.models[id]
if !ok {
return nil, errors.Errorf("(peek) coder with id %v not found", id)
}
return c, nil
}
func (b *CoderUnmarshaller) isCoGBKList(id string) ([]string, bool) {
elm, err := b.peek(id)
if err != nil {
return nil, false
}
if elm.GetSpec().GetUrn() != urnLengthPrefixCoder {
return nil, falseView on GitHub (pinned to 12126d8942)