apache/beam · error · CannotProvideCoderException

Cannot provide a coder for a Beam Row. Please provide a sche

Error message

Cannot provide a coder for a Beam Row. Please provide a schema instead using PCollection.setRowSchema.

What it means

Beam Rows cannot be encoded with a traditional Coder; they are serialized via a Schema instead. When getCoderFromTypeDescriptor is asked for a coder whose type is TypeDescriptors.rows(), it fails fast with CannotProvideCoderException pointing the user to set a schema on the PCollection. This prevents users from trying to route Row data through the coder registry.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderRegistry.java:611

    return c == null || c.isEmpty();
  }

  /** The list of {@link CoderProvider coder providers} to use to provide Coders. */
  private ArrayDeque<CoderProvider> coderProviders;

  /**
   * Returns a {@link Coder} to use for values of the given type, in a context where the given types
   * use the given coders.
   *
   * @throws CannotProvideCoderException if a coder cannot be provided
   */
  private <T> Coder<T> getCoderFromTypeDescriptor(
      TypeDescriptor<T> typeDescriptor, SetMultimap<Type, Coder<?>> typeCoderBindings)
      throws CannotProvideCoderException {
    Type type = typeDescriptor.getType();
    Coder<?> coder;
    if (typeDescriptor.equals(TypeDescriptors.rows())) {
      throw new CannotProvideCoderException(
          "Cannot provide a coder for a Beam Row. Please provide a schema instead using PCollection.setRowSchema.");
    }
    if (typeCoderBindings.containsKey(type)) {
      Set<Coder<?>> coders = typeCoderBindings.get(type);
      if (coders.size() == 1) {
        coder = Iterables.getOnlyElement(coders);
      } else {
        throw new CannotProvideCoderException(
            String.format(
                "Cannot provide a coder for type variable %s"
                    + " because the actual type is over specified by multiple"
                    + " incompatible coders %s.",
                type, coders),
            ReasonCode.OVER_SPECIFIED);
      }
    } else if (type instanceof Class<?>) {
      coder = getCoderFromFactories(typeDescriptor, Collections.emptyList());
    } else if (type instanceof ParameterizedType) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Attach a schema instead: pcollection.setRowSchema(mySchema) — the schema determines serialization.
  2. Ensure upstream transforms producing Rows use Schema-aware PTransforms so no coder is needed.
  3. Refactor helper code to special-case TypeDescriptors.rows() before requesting a coder.

Example fix

// before
Coder<Row> coder = registry.getCoder(TypeDescriptor.of(Row.class));
// after
pcollection.setRowSchema(Schema.builder().addStringField("name").build());
Defensive patterns

Strategy: type-guard

Validate before calling

if (TypeDescriptors.rows().equals(typeDescriptor)) {
  throw new IllegalArgumentException("Use setRowSchema for Rows, not a coder");
}

Type guard

boolean isRow = TypeDescriptors.rows().equals(typeDescriptor);

Try / catch

try {
  coder = registry.getCoder(td);
} catch (CannotProvideCoderException e) {
  // if message mentions Row, attach a schema via setRowSchema instead
}

Prevention

When it happens

Trigger: Calling CoderRegistry.getCoder(TypeDescriptor.of(Row.class)) or TypeDescriptors.rows(); letting the registry infer a coder for a PCollection<Row> without an associated schema.

Common situations: Converting schema-agnostic pipeline code to schema-udf/Row-based processing; generic helper methods that call getCoder on arbitrary TypeDescriptors that may be Row.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/8b718041c59f0cef. Report an issue: GitHub.