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
- Register the class with Kryo (e.g. via KryoOptions registrations or a KryoRegistrar) so hasUserProvidedRegistration succeeds.
- Annotate the type with @DefaultCoder or supply an explicit Coder via setCoder.
- If truly dynamic/untyped use is intended, pass a TypeDescriptor for java.lang.Object, which the provider short-circuits.
- 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
- Register every custom type passed through Beam PCollections
- Use @DefaultCoder for types with a fixed coder
- Run coder inference in unit tests before launching jobs
- Prefer Beam-native coders for simple POJOs
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
- ApproximateUnique.PerKey requires its input to use KvCoder
- AvroCoder for GenericRecord requires a schema
- Cannot decode object from input stream.
- cannot encode a null BitSet
- cannot encode a null byte[]
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)