apache/beam · error · java.lang.RuntimeException
cannot register component
Error message
cannot register component: %s
What it means
In External.expand (cross-language pipeline expansion), components such as fake Impulse PTransforms are registered into the components builder before sending the expansion request. If registering a component throws IOException, it is wrapped as RuntimeException 'cannot register component: <message>'. It indicates a failure serializing/adding a component to the expansion request's components map.
Solutions
- Check the wrapped cause message (it is appended to the RuntimeException message) to find the underlying IOException
- Verify the external transform's inputs/coders are well-formed before expansion
- Ensure the expansion service and SDK versions are compatible and the service is reachable/restart it
Defensive patterns
Strategy: try-catch
Try / catch
try { external.expand(pipeline.apply(Create.of(...))); } catch (RuntimeException e) { if (e.getMessage().startsWith("cannot register component:")) { log.error("expansion component registration failed", e); /* inspect cause and expansion service */ } } Prevention
- Keep the expansion service version-compatible with the SDK
- Validate external transform inputs before expand
- Check expansion service logs alongside the wrapped message
When it happens
Trigger: Calling External.of(...).expand(...) where building/registering the fake impulse or input components fails — e.g. an underlying IOException from coder/transform registration in the components builder.
Common situations: Cross-language transforms (Python/Scala via expansion service) with inputs that fail component registration; I/O errors while writing proto components; malformed transform payloads in the expansion request path.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- BigQueryIO.Write transforms cannot be converted to a…
- Cannot create from non-Java
- Class name must not be empty
- A function must be provided to convert the input type into…
- A PValue contained in
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b566b38a7ffc000c.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/External.java:251
if (entry.getValue() instanceof PCollection<?>) {
try {
String id = components.registerPCollection((PCollection) entry.getValue());
externalPCollectionIdMapBuilder.put((PCollection) entry.getValue(), id);
ptransformBuilder.putInputs(entry.getKey().getId(), id);
AppliedPTransform<?, ?, ?> fakeImpulse =
AppliedPTransform.of(
String.format("%s_%s", IMPULSE_PREFIX, entry.getKey().getId()),
PValues.expandInput(PBegin.in(p)),
ImmutableMap.of(entry.getKey(), (PCollection<?>) entry.getValue()),
Impulse.create(),
// TODO(https://github.com/apache/beam/issues/18371): Add proper support for
// Resource Hints with XLang.
ResourceHints.create(),
p);
// using fake Impulses to provide inputs
components.registerPTransform(fakeImpulse, Collections.emptyList());
} catch (IOException e) {
throw new RuntimeException(
String.format("cannot register component: %s", e.getMessage()));
}
}
}
ExpansionApi.ExpansionRequest.Builder requestBuilder =
ExpansionApi.ExpansionRequest.newBuilder();
requestBuilder.putAllOutputCoderRequests(
outputCoders.entrySet().stream()
.collect(
Collectors.toMap(
Map.Entry::getKey,
kv -> {
try {
return components.registerCoder(kv.getValue());
} catch (IOException e) {
throw new RuntimeException(e);
}View on GitHub (pinned to 12126d8942)