apache/beam · error · CannotProvideCoderException

Cannot provide coder for parameterized type %s: %s

Error message

Cannot provide coder for parameterized type %s: %s

What it means

While resolving coders for a parameterized type's arguments, at least one type argument itself could not get a coder. getCoderFromParameterizedType catches that CannotProvideCoderException and rethrows a new one with this message, which names the whole parameterized type and the underlying reason, preserving the cause. It is a contextual wrapper, not a distinct failure mode.

Source

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

  /**
   * Returns a {@link Coder} to use for values of the given parameterized type, in a context where
   * the given types use the given {@link Coder Coders}.
   *
   * @throws CannotProvideCoderException if no coder can be provided
   */
  private Coder<?> getCoderFromParameterizedType(
      ParameterizedType type, SetMultimap<Type, Coder<?>> typeCoderBindings)
      throws CannotProvideCoderException {

    List<Coder<?>> typeArgumentCoders = new ArrayList<>();
    for (Type typeArgument : type.getActualTypeArguments()) {
      try {
        Coder<?> typeArgumentCoder =
            getCoderFromTypeDescriptor(TypeDescriptor.of(typeArgument), typeCoderBindings);
        typeArgumentCoders.add(typeArgumentCoder);
      } catch (CannotProvideCoderException exc) {
        throw new CannotProvideCoderException(
            String.format(
                "Cannot provide coder for parameterized type %s: %s", type, exc.getMessage()),
            exc);
      }
    }
    return getCoderFromFactories(TypeDescriptor.of(type), typeArgumentCoders);
  }

  /**
   * Attempts to create a {@link Coder} from any registered {@link CoderProvider} returning the
   * first successfully created instance.
   */
  private Coder<?> getCoderFromFactories(
      TypeDescriptor<?> typeDescriptor, List<Coder<?>> typeArgumentCoders)
      throws CannotProvideCoderException {
    List<CannotProvideCoderException> suppressedExceptions = new ArrayList<>();
    for (CoderProvider coderProvider : coderProviders) {
      try {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Read the exception cause to find the exact failing type argument.
  2. Register a coder for the failing type via registerCoderForType or implement a CoderFactory / @DefaultCoder annotation on the class.
  3. Replace the uncodable type argument with a codable one.

Example fix

// before
// KV<MyPojo, Integer> with no coder for MyPojo
// after
registry.registerCoderForType(TypeDescriptor.of(MyPojo.class), new MyPojoCoder());
Defensive patterns

Strategy: try-catch

Validate before calling

for (Type arg : ((ParameterizedType) type).getActualTypeArguments()) {
  try { registry.getCoder(TypeDescriptor.of(arg)); }
  catch (CannotProvideCoderException e) { /* arg needs a registered coder */ }
}

Try / catch

try {
  coder = registry.getCoder(parameterizedDescriptor);
} catch (CannotProvideCoderException e) {
  // inspect e.getCause() for the failing type argument, register a coder, retry
}

Prevention

When it happens

Trigger: getCoder on a ParameterizedType (e.g. Map<K,V>, Pair<A,B>) where any actual type argument fails getCoderFromTypeDescriptor — no registered coder/factory for it, wildcard argument, over-specified binding, etc.

Common situations: KV<CustomType, String> where CustomType lacks a registered coder; nested generics like List<Map<String, MyPojo>> with an uncodable leaf type; using a type variable in an anonymous subclass that resolves to nothing.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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