apache/beam · error · java.lang.RuntimeException
cannot rehydrate Coder.
Error message
cannot rehydrate Coder.
What it means
During External.expand(), coders referenced by expanded output PCollections are rehydrated so Java can map them back to coder ids. An IOException from rehydratedComponents.getCoder(coderId) is caught and rethrown as this opaque RuntimeException, meaning the returned coder graph referenced a coder that could not be constructed.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/External.java:333
} catch (IOException e) {
throw new RuntimeException("cannot rehydrate PCollection.");
}
});
externalPCollectionIdMap = externalPCollectionIdMapBuilder.build();
Map<Coder<?>, String> externalCoderIdMapBuilder = new HashMap<>();
expandedComponents
.getPcollectionsMap()
.forEach(
(pcolId, pCol) -> {
try {
String coderId = pCol.getCoderId();
if (isJavaSDKCompatible(expandedComponents, coderId)) {
Coder<?> coder = rehydratedComponents.getCoder(coderId);
externalCoderIdMapBuilder.putIfAbsent(coder, coderId);
}
} catch (IOException e) {
throw new RuntimeException("cannot rehydrate Coder.");
}
});
externalCoderIdMap = ImmutableMap.copyOf(externalCoderIdMapBuilder);
return toOutputCollection(outputMapBuilder.build());
}
static Map<String, RunnerApi.Environment> resolveArtifacts(
Map<String, RunnerApi.Environment> environments, Endpoints.ApiServiceDescriptor endpoint) {
if (environments.size() == 0) {
return environments;
}
ManagedChannel channel =
ManagedChannelBuilder.forTarget(endpoint.getUrl())
.usePlaintext()
.maxInboundMessageSize(Integer.MAX_VALUE)
.build();
try {View on GitHub (pinned to 12126d8942)
Solutions
- Check isJavaSDKCompatible filtering and ensure the transform's outputs use Java-compatible coders.
- Align Beam SDK and expansion service versions so coder proto definitions match.
- Register the missing custom coder with the Java SDK (CoderProvider) so it can be constructed.
- Preserve the cause: `throw new RuntimeException("cannot rehydrate Coder.", e)` when editing this code path.
Example fix
// before
throw new RuntimeException("cannot rehydrate Coder.");
// after
throw new RuntimeException("cannot rehydrate Coder: " + coderId, e); Defensive patterns
Strategy: try-catch
Validate before calling
null
Try / catch
try { external.expand(...); } catch (RuntimeException e) { if ("cannot rehydrate Coder.".equals(e.getMessage())) { /* check coder registration / SDK version skew */ } throw e; } Prevention
- Register custom coders via CoderProvider with the Java SDK
- Keep expansion service and SDK versions matched
- Prefer standard coders for cross-language transform outputs
When it happens
Trigger: The expansion response contains a pCollection whose coderId is absent from components.coders or whose payload cannot be parsed into a Java Coder during expansion of a cross-language transform.
Common situations: Cross-language transforms emitting coders unknown to the Java SDK; version skew between SDK and expansion service; custom coders not registered on the Java side.
Related errors
- Timing number 0b" + timingNumber.toString(2) + " has more th
- No proto encoding for PaneInfoCoder, always part of Windowed
- cannot encode a null Integer
- cannot encode a null Long
- cannot encode a null Short
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0424554abf31c276.
Report an issue: GitHub.