apache/beam · error · CannotProvideCoderException

Cannot provide [ ], given type descriptor's [ ] raw type is…

Error message

Cannot provide [%s], given type descriptor's [%s] raw type is not registered in Kryo.

What it means

KryoCoderProvider.coderFor is asked to supply a Coder for a type. If the type is not explicitly registered with Kryo (no user-provided registration) and is not plain java.lang.Object, the provider cannot safely hand out a KryoCoder and throws CannotProvideCoderException. This prevents silently serializing unregistered classes when registration is expected.

Solutions

  1. Register the class with Kryo (e.g. via KryoOptions registrations or a KryoRegistrar) so hasUserProvidedRegistration succeeds.
  2. Annotate the type with @DefaultCoder or supply an explicit Coder via setCoder.
  3. If truly dynamic/untyped use is intended, pass a TypeDescriptor for java.lang.Object, which the provider short-circuits.
  4. Switch the class to a registered serializable type or a Beam-native coder (SerializableCoder/AvroCoder).

Example fix

// before
PCollection<MyPojo> out = pipeline.apply(...); // MyPojo unregistered -> CannotProvideCoderException
// after
KryoOptions options = KryoOptions.widenBytesAndStrings(false).withRegistrations(ImmutableList.of(new Registration(MyPojo.class, 1000)));
PCollection<MyPojo> out = pipeline.apply(...).setCoder(KryoCoder.of(options));
Defensive patterns

Strategy: validation

Validate before calling

KryoOptions options = ...; if (!options.isRegistered(MyPojo.class)) registerOrProvideCoder(MyPojo.class);

Try / catch

try { Coder<T> c = registry.getCoder(TypeDescriptor.of(MyPojo.class)); } catch (CannotProvideCoderException e) { /* register type and retry */ }

Prevention

When it happens

Trigger: Calling CoderRegistry.getCoder(TypeDescriptor) (or using a pipeline where coder inference runs) for a class that has no Kryo registration and no user-provided coder, when the Kryo configuration requires explicit registration.

Common situations: Passing a custom POJO through a Beam pipeline without registering it via KryoOptions/registration or @DefaultCoder; refactoring a type so coder inference no longer finds a registered Kryo mapping.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/extensions/kryo/src/main/java/org/apache/beam/sdk/extensions/kryo/KryoCoderProvider.java:128

  /** {@link KryoRegistrar}s associated with this provider instance. */
  private final KryoCoder<?> coder;

  private KryoCoderProvider(KryoCoder<?> coder) {
    this.coder = coder;
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T> Coder<T> coderFor(
      TypeDescriptor<T> typeDescriptor, List<? extends Coder<?>> componentCoders)
      throws CannotProvideCoderException {
    if (hasUserProvidedRegistration(typeDescriptor)) {
      return (Coder) coder;
    }
    if (OBJECT_TYPE.equals(typeDescriptor)) {
      return (Coder) coder;
    }
    throw new CannotProvideCoderException(
        String.format(
            "Cannot provide [%s], given type descriptor's [%s] raw type is not registered in Kryo.",
            KryoCoder.class.getSimpleName(), typeDescriptor));
  }

  private <T> boolean hasUserProvidedRegistration(TypeDescriptor<T> typeDescriptor) {
    final KryoState kryoState = KryoState.get(coder);
    final Class<? super T> rawType = typeDescriptor.getRawType();
    final Kryo kryo = kryoState.getKryo();
    final ClassResolver classResolver = kryo.getClassResolver();
    final Registration registration = classResolver.getRegistration(rawType);
    return registration != null && registration.getId() >= kryoState.getFirstRegistrationId();
  }

  /**
   * Create a new {@link KryoCoderProvider} with the provided registrar.
   *
   * @param registrar registrar to append to the list of already registered registrars.

View on GitHub (pinned to 12126d8942)