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

  1. Ensure the PCollection element type is Mutation (or a Put/Delete) when relying on the default coder.
  2. If your type is RowMutations, HBaseRowMutationsCoder handles it — do not expect the Mutation coder to apply.
  3. Register your own Coder explicitly for non-Mutation types instead of relying on this provider.
  4. 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

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


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)