apache/beam · warning · CannotProvideCoderException
Cannot provide because is not a subclass of
Error message
Cannot provide %s because %s is not a subclass of %s
What it means
HBaseRowMutationsCoderProvider supplies HBaseRowMutationsCoder only for TypeDescriptors that are subtypes of RowMutations (descriptor check against HBASE_ROW_MUTATIONS_TYPE_DESCRIPTOR; the message text mentions Mutation). If the requested type isn't a match, it throws CannotProvideCoderException — expected behavior of the CoderProvider SPI.
Solutions
- Ensure the PCollection element type is exactly RowMutations when relying on this provider.
- Use HBaseIO's expected types (Mutation for HBaseMutationCoder, RowMutations for this coder) or set the coder explicitly with setCoder().
- Handle CannotProvideCoderException when querying coder registry programmatically and fall back to a registered coder.
- Register your own Coder for custom wrapper types instead of relying on inference.
Example fix
// before
PCollection<MyWrapper> wrapped = ...; // no coder found
// after
PCollection<RowMutations> rms = wrapped.apply(MapElements.into(TypeDescriptor.of(RowMutations.class))...)
.setCoder(HBaseRowMutationsCoder.of()); Defensive patterns
Strategy: type-guard
Validate before calling
TypeDescriptor<?> td = TypeDescriptor.of(pcoll.getCoder().getEncodedTypeDescriptor());
if (!td.isSubtypeOf(TypeDescriptor.of(RowMutations.class))) {
pcoll.setCoder(HBaseRowMutationsCoder.of()); // only for RowMutations collections
} Type guard
static <T> boolean isRowMutationsType(TypeDescriptor<T> td) {
return td.isSubtypeOf(TypeDescriptor.of(RowMutations.class));
} Try / catch
try {
Coder<?> c = coderRegistry.getCoder(TypeDescriptor.of(MyWrapper.class));
} catch (CannotProvideCoderException e) {
// unwrap to RowMutations or register an explicit coder
pcoll.setCoder(HBaseRowMutationsCoder.of());
} Prevention
- Use RowMutations as the element type for multi-mutation-per-row writes.
- Set HBaseRowMutationsCoder.of() explicitly instead of relying on inference.
- Catch CannotProvideCoderException in coder-registry lookups and provide fallbacks.
- Keep custom wrapper types registered with their own coders.
When it happens
Trigger: Beam coder registry asks this provider for a coder for type T; T is neither RowMutations nor a Mutation subtype, so the provider declines.
Common situations: Requesting default coders for POJOs or wrappers around RowMutations; confusion between Mutation-level coder and RowMutations coder; generic pipeline code losing concrete type info.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Cannot provide because is not a subclass of
- Mutation type not supported.
- Only Put and Delete are supported
- Only Put and Delete are supported
- ApproximateUnique.PerKey requires its input to use KvCoder
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2588826666085814.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseRowMutationsCoder.java:126
/**
* Returns a {@link CoderProvider} which uses the {@link HBaseRowMutationsCoder} for {@link
* RowMutations}.
*/
static CoderProvider getCoderProvider() {
return HBASE_ROW_MUTATIONS_CODER_PROVIDER;
}
private static final CoderProvider HBASE_ROW_MUTATIONS_CODER_PROVIDER =
new HBaseRowMutationsCoderProvider();
/** A {@link CoderProvider} for {@link Mutation mutations}. */
private static class HBaseRowMutationsCoderProvider extends CoderProvider {
@Override
public <T> Coder<T> coderFor(
TypeDescriptor<T> typeDescriptor, List<? extends Coder<?>> componentCoders)
throws CannotProvideCoderException {
if (!typeDescriptor.isSubtypeOf(HBASE_ROW_MUTATIONS_TYPE_DESCRIPTOR)) {
throw new CannotProvideCoderException(
String.format(
"Cannot provide %s because %s is not a subclass of %s",
HBaseRowMutationsCoder.class.getSimpleName(),
typeDescriptor,
Mutation.class.getName()));
}
try {
@SuppressWarnings("unchecked")
Coder<T> coder = (Coder<T>) HBaseRowMutationsCoder.of();
return coder;
} catch (IllegalArgumentException e) {
throw new CannotProvideCoderException(e);
}
}
}
private static final TypeDescriptor<RowMutations> HBASE_ROW_MUTATIONS_TYPE_DESCRIPTOR =View on GitHub (pinned to 12126d8942)