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
- Read the wrapped cause for the specific window coder failure
- Use built-in windows (GlobalWindows, FixedWindows, etc.) or ensure custom windows decode via the registered custom window handling
- Align SDK versions between producer and harness
- 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
- Use built-in windows in timer pipelines
- Register custom window encodings before graph decode
- Match SDK versions across submitter and harness
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
- unwindowed coder %v on DataSource %v: %v
- could not unmarshal window coder for pcollection %v: %w
- unwindowed coder %v on DataSink %v: %v
- could not unmarshal global window coder: %w
- window must not be nil
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/496de0e537776af0.
Report an issue: GitHub.