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
HBaseMutationCoderProvider is a CoderProvider that can only supply HBaseMutationCoder for types that are subtypes of Mutation. coderFor throws CannotProvideCoderException when the requested TypeDescriptor is not a Mutation subtype — this is the normal coder-resolution failure signal, not a bug.
Solutions
- Ensure the PCollection element type is Mutation (or a Put/Delete) when relying on the default coder.
- If your type is RowMutations, HBaseRowMutationsCoder handles it — do not expect the Mutation coder to apply.
- Register your own Coder explicitly for non-Mutation types instead of relying on this provider.
- This exception is often expected control flow — catch it and fall back to another coder provider.
Example fix
// before
p.apply("Read", ...)
.setCoder(null); // wrong coder for non-Mutation type
// after
PCollection<Mutation> mutations =
p.apply(...).setCoder(HBaseMutationCoder.of()); Defensive patterns
Strategy: type-guard
Validate before calling
TypeDescriptor<?> td = TypeDescriptor.of(elementType);
if (!td.isSubtypeOf(TypeDescriptor.of(Mutation.class))) {
// supply your own coder before this point
collection.setCoder(myExplicitCoder);
} Type guard
static <T> boolean isMutationType(TypeDescriptor<T> td) {
return td.isSubtypeOf(TypeDescriptor.of(Mutation.class));
} Try / catch
try {
Coder<?> c = coderRegistry.getCoder(typeDescriptor);
} catch (CannotProvideCoderException e) {
// fall back to a registered/default coder or fix the element type
collection.setCoder(SerializableCoder.of(MyType.class));
} Prevention
- Keep PCollection element types concrete (Mutation, Put, Delete) near HBaseIO stages.
- Set coders explicitly with setCoder() rather than relying on registry inference.
- Catch CannotProvideCoderException when doing programmatic coder lookup and fall back.
- Don't confuse HBaseMutationCoder (Mutation) with HBaseRowMutationsCoder (RowMutations).
When it happens
Trigger: Beam's coder registry asks this provider for a coder for a type T; if T is not assignable to org.apache.hadoop.hbase.client.Mutation, the provider declines via CannotProvideCoderException.
Common situations: Pipelines whose PCollection element type resembles but isn't Mutation (e.g. RowMutations, a wrapper, or byte[]); relying on default coder inference for non-Mutation types near HBaseIO usage.
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/07d40bdc9a3f3c4b.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseMutationCoder.java:91
/**
* Returns a {@link CoderProvider} which uses the {@link HBaseMutationCoder} for {@link Mutation
* mutations}.
*/
static CoderProvider getCoderProvider() {
return HBASE_MUTATION_CODER_PROVIDER;
}
private static final CoderProvider HBASE_MUTATION_CODER_PROVIDER =
new HBaseMutationCoderProvider();
/** A {@link CoderProvider} for {@link Mutation mutations}. */
private static class HBaseMutationCoderProvider extends CoderProvider {
@Override
public <T> Coder<T> coderFor(
TypeDescriptor<T> typeDescriptor, List<? extends Coder<?>> componentCoders)
throws CannotProvideCoderException {
if (!typeDescriptor.isSubtypeOf(HBASE_MUTATION_TYPE_DESCRIPTOR)) {
throw new CannotProvideCoderException(
String.format(
"Cannot provide %s because %s is not a subclass of %s",
HBaseMutationCoder.class.getSimpleName(),
typeDescriptor,
Mutation.class.getName()));
}
try {
@SuppressWarnings("unchecked")
Coder<T> coder = (Coder<T>) HBaseMutationCoder.of();
return coder;
} catch (IllegalArgumentException e) {
throw new CannotProvideCoderException(e);
}
}
}
private static final TypeDescriptor<Mutation> HBASE_MUTATION_TYPE_DESCRIPTOR =View on GitHub (pinned to 12126d8942)