apache/beam · error
Nullable coder must have only one component
Error message
Nullable coder must have only one component: %s
What it means
Error returned by the Prism runner's pullDecoderNoAlloc when a nullable coder's component list does not contain exactly one entry. Nullable coders wrap a single inner element coder; any other component count means the coder proto coming from the pipeline is malformed, and the message prints the offending coder for inspection.
Solutions
- Fix the pipeline so the Nullable coder declares exactly one component coder ID
- Upgrade the producing SDK to a version emitting spec-compliant Nullable coders
- Inspect the formatted coder in the panic message (prototext) to see the offending component list
- If generated by custom code, correct the coder construction to wrap a single component
Example fix
// before
&pipepb.Coder{Spec: nullableUrn, ComponentCoderIds: []string{}},
// after
&pipepb.Coder{Spec: nullableUrn, ComponentCoderIds: []string{"c0"}}, Defensive patterns
Strategy: validation
Validate before calling
if c.GetSpec().GetUrn() == "beam:coder:nullable:v1" && len(c.GetComponentCoderIds()) != 1 {
return fmt.Errorf("invalid nullable coder: %v", c)
} Try / catch
defer func() {
if r := recover(); r != nil && strings.Contains(fmt.Sprint(r), "Nullable coder must have only one component") {
err = fmt.Errorf("malformed nullable coder in pipeline: %v", r)
}
}() Prevention
- Emit Nullable coders with exactly one component
- Regenerate pipelines with a current Beam SDK
- Validate coder component counts before job submission
- Inspect prototext dumps when coders come from external tools
When it happens
Trigger: A pipeline contains a beam:coder:nullable:v1 coder whose component list is empty or has more than one component coder ID, decoded when prism builds stream decoders.
Common situations: Malformed pipeline protos from other SDK versions or third-party tools emitting non-conforming Nullable coders; hand-constructed coder payloads in tests.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Iterable coder must have only one component
- makeWindowCoders, unknown urn
- unknown coder id during reconciliation
- A VPC network must be provided to use a private endpoint.
- An invalid input " " was specified in "fields".
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a2e0fbca0f24706a.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/runners/prism/internal/coders.go:309
}
}
// pullDecoderNoAlloc returns a function that decodes a single element of the given coder.
// Intended to only be used as an internal function for pullDecoder, which will use a io.TeeReader
// to extract the bytes.
func pullDecoderNoAlloc(c *pipepb.Coder, coders map[string]*pipepb.Coder) func(io.Reader) {
urn := c.GetSpec().GetUrn()
switch urn {
// Anything length prefixed can be treated as opaque.
case urns.CoderBytes, urns.CoderStringUTF8, urns.CoderLengthPrefix:
return func(r io.Reader) {
l, _ := coder.DecodeVarInt(r)
ioutilx.ReadN(r, int(l))
}
case urns.CoderNullable:
ccids := c.GetComponentCoderIds()
if len(ccids) != 1 {
panic(fmt.Sprintf("Nullable coder must have only one component: %s", prototext.Format(c)))
}
ed := pullDecoderNoAlloc(coders[ccids[0]], coders)
return func(r io.Reader) {
b, _ := ioutilx.ReadN(r, 1)
if len(b) == 0 {
return
}
// Nullable coder is prefixed with 0 or 1 to indicate whether there exists remaining data.
prefix := b[0]
if prefix == 0 {
return
}
ed(r)
}
case urns.CoderVarInt:
return func(r io.Reader) {
coder.DecodeVarInt(r)
}View on GitHub (pinned to 12126d8942)