apache/beam · error

could not unmarshal window coder for timer: %w

Error message

could not unmarshal window coder for timer: %w

What it means

Error returned by makeCoder when the second component of a timer coder (the window coder, resolved via b.WindowCoder) fails to decode. The underlying error is wrapped, meaning the timer's windowing strategy coder referenced by the pipeline proto is itself invalid or unresolvable in this coder environment.

Source

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

		if len(components) != 1 {
			return nil, errors.Errorf("could not unmarshal iterable coder from %v, expected one component but got %d", c, len(components))
		}
		elm, err := b.Coder(components[0])
		if err != nil {
			return nil, err
		}
		return coder.NewI(elm), nil
	case urnTimerCoder:
		if len(components) != 2 {
			return nil, errors.Errorf("could not unmarshal timer coder from %v, expected two component but got %d", c, len(components))
		}
		elm, err := b.Coder(components[0])
		if err != nil {
			return nil, err
		}
		w, err := b.WindowCoder(components[1])
		if err != nil {
			return nil, errors.Errorf("could not unmarshal window coder for timer: %w", err)
		}
		return coder.NewT(elm, w), nil
	case urnRowCoder:
		var s pipepb.Schema
		if err := proto.Unmarshal(c.GetSpec().GetPayload(), &s); err != nil {
			return nil, err
		}
		t, err := schema.ToType(&s)
		if err != nil {
			return nil, err
		}
		return coder.NewR(typex.New(t)), nil
	case urnNullableCoder:
		if len(components) != 1 {
			return nil, errors.Errorf("could not unmarshal nullable coder from %v, expected one component but got %d", c, len(components))
		}
		elm, err := b.Coder(components[0])
		if err != nil {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Read the wrapped cause for the specific window coder failure
  2. Use built-in windows (GlobalWindows, FixedWindows, etc.) or ensure custom windows decode via the registered custom window handling
  3. Align SDK versions between producer and harness
  4. Validate the timer coder's second component is a valid window coder

Example fix

// before: timer coder window component referencing unregistered custom window
// after: use beam.FixedWindows(...) / GlobalWindows or register the custom window type before decoding
Defensive patterns

Strategy: try-catch

Validate before calling

// validate the timer's window component decodes before decoding the timer
if len(ref.Components) == 2 {
    if _, err := graphx.WindowCoderFromJSON([]byte(ref.Components[1].Payload)); err != nil {
        return fmt.Errorf("timer window component invalid: %w", err)
    }
}

Try / catch

tc, err := graphx.Coder(model, ref)
if err != nil {
    if strings.Contains(err.Error(), "window coder") {
        return fmt.Errorf("timer windowing unsupported on this harness: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Decoding a timer coder whose window-coder component uses an unsupported URN or has a corrupt payload, e.g. custom windows unknown to the harness.

Common situations: Custom window functions serialized but not registered on the decoding harness; SDK version mismatch for window coder encodings; corrupted pipeline payloads.

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/496de0e537776af0. Report an issue: GitHub.