apache/beam · error

could not unmarshal window coder

Error message

could not unmarshal window coder: %w

What it means

CoderUnmarshaller.WindowCoder resolves the window coder for a given ID by peeking at the raw coder proto. If peeking (which recursively unmarshals) fails, the error is wrapped as "could not unmarshal window coder: %w". It indicates a failure while decoding the windowing coder portion of a PCollection.

Solutions

  1. Inspect the wrapped cause (%w) — it usually points to a missing or invalid component coder.
  2. Ensure all component coder IDs referenced by the window coder exist in the pipeline proto.
  3. Re-marshal the pipeline with a matching SDK version if it was produced by a different Beam release.
  4. If hand-crafting windowed coders, verify the coder spec URN and payload are valid.
Defensive patterns

Strategy: try-catch

Try / catch

w, err := um.WindowCoder(id)
if err != nil && strings.Contains(err.Error(), "could not unmarshal window coder") {
    log.Printf("inspect wrapped cause and fix component coders: %v", err)
}

Prevention

When it happens

Trigger: makeCoderForPCollection or makeCoder resolving a windowed PCollection's window coder when the underlying component coder fails to peek/unmarshal (missing component, bad coder ID, unsupported nested coder).

Common situations: Corrupted or incomplete pipeline protos; coder component IDs referencing nonexistent coders; cross-version pipeline serialization where nested coder payloads changed format.

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/95380ced9e1be983. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/graphx/coder.go:167

	ret, err := b.makeCoder(id, c)
	if err != nil {
		return nil, errors.WithContextf(err, "unmarshalling coder %v", id)
	}
	ret.ID = id

	b.coders[id] = ret
	return ret, nil
}

// WindowCoder unmarshals a window coder with the given id.
func (b *CoderUnmarshaller) WindowCoder(id string) (*coder.WindowCoder, error) {
	if w, exists := b.windowCoders[id]; exists {
		return w, nil
	}

	c, err := b.peek(id)
	if err != nil {
		return nil, errors.Errorf("could not unmarshal window coder: %w", err)
	}

	w, err := urnToWindowCoder(c.GetSpec().GetUrn())
	if err != nil {
		return nil, errors.SetTopLevelMsgf(err, "failed to unmarshal window coder %v", id)
	}
	b.windowCoders[id] = w
	return w, nil
}

func urnToWindowCoder(urn string) (*coder.WindowCoder, error) {
	switch urn {
	case urnGlobalWindow:
		return coder.NewGlobalWindow(), nil
	case urnIntervalWindow:
		return coder.NewIntervalWindow(), nil
	default:
		err := errors.Errorf("unexpected URN %v for window coder", urn)

View on GitHub (pinned to 12126d8942)