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

  1. Ensure the PCollection element type is exactly RowMutations when relying on this provider.
  2. Use HBaseIO's expected types (Mutation for HBaseMutationCoder, RowMutations for this coder) or set the coder explicitly with setCoder().
  3. Handle CannotProvideCoderException when querying coder registry programmatically and fall back to a registered coder.
  4. 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

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


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)