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

  1. Upgrade the Go Beam SDK to the same or newer version that produced the pipeline so the URN is recognized
  2. 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
  3. If the pipeline uses a custom coder, ensure it was registered with beam.RegisterType on the Go side before deserialization
  4. 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

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


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, false

View on GitHub (pinned to 12126d8942)