apache/beam · error
Unexpected transform URN
Error message
Unexpected transform URN: %v
What it means
makeLink translates graph transform URNs into executable units and handles a fixed set of known URNs (ParDo, Combine, sinks, ToString, etc.). A URN outside that set hits the default case and panics with 'Unexpected transform URN'. This guards against pipelines containing transforms the Go exec translator cannot lower.
Solutions
- Upgrade the Go SDK/worker container to match (or exceed) the SDK that produced the pipeline
- Ensure cross-language transforms are fully expanded before Go execution (check expansion service logs)
- Search the pipeline graph dump for the offending URN and replace the transform with a supported equivalent (e.g. use ParDo with a DoFn)
- If it's a legitimately supported transform failing to translate, file a Beam issue with the URN and pipeline
Example fix
// before (pipeline uses URN the worker can't lower)
beam.CrossLanguage(p, "my:custom:urn", ...)
// after
// expand cross-language transform before Go execution, or implement with a Go ParDo:
beam.ParDo(p, &myGoDoFn{}, input) Defensive patterns
Strategy: validation
Validate before calling
known := map[string]bool{graphx.URNParDoTransform: true, graphx.URNToString: true /* ... */}
if !known[urn] {
return fmt.Errorf("transform URN %q is not supported by this Go SDK version", urn)
} Prevention
- Keep the Go worker image at least as new as the submitting SDK
- Fully expand cross-language transforms before Go execution
- Avoid custom URNs unless you control the translation path
- Check expansion logs when mixing Python/Java with Go runners
When it happens
Trigger: A pipeline graph containing an unknown/exotic URN (e.g. a cross-language transform not materialized before execution, or a newer SDK URN unknown to the worker); hand-edited or corrupted graph JSON; version skew where the submitting SDK emits URNs the worker's translator predates.
Common situations: Cross-language (Python/Java → Go) pipelines where expansion didn't fully resolve URNs; newer Beam features used with an older Go worker container; custom transforms registered under a custom URN executed with the direct Go runner path.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Opcode should be one of ParDo or Combine, but it is
- AfterProcessingTime trigger set without a delay or…
- array len mismatch. decoding
- At least one subtrigger required for composite triggers.
- attempted to add namespace to missing coder id
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/02826f2f30dc7a79.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/exec/translate.go:834
return nil, err
}
sink := &DataSink{UID: b.idgen.New()}
sink.SID = StreamID{PtransformID: id.to, Port: port}
sink.Coder, err = b.coders.Coder(cid) // Expected to be windowed coder
if err != nil {
return nil, err
}
if !coder.IsW(sink.Coder) {
return nil, errors.Errorf("unwindowed coder %v on DataSink %v: %v", cid, id, sink.Coder)
}
u = sink
case graphx.URNToString:
u = &ToString{UID: b.idgen.New(), Out: out[0]}
default:
panic(fmt.Sprintf("Unexpected transform URN: %v", urn))
}
b.links[id] = u
b.units = append(b.units, u)
return u, nil
}
func unmarshalReshuffleCoders(mainID string, payloads map[string][]byte) (*coder.Coder, error) {
m := map[string]*pipepb.Coder{}
for id, v := range payloads {
pc := &pipepb.Coder{}
if err := proto.Unmarshal(v, pc); err != nil {
return nil, err
}
m[id] = pc
}
um := graphx.NewCoderUnmarshaller(m)
return um.Coder(mainID)View on GitHub (pinned to 12126d8942)