apache/beam · error · IncompatibleCoderException
Cannot encode elements of type
Error message
Cannot encode elements of type %s with coder %s because the coded type %s is not assignable from %s
What it means
verifyCompatible rejects a coder when the raw class it is coded for (codedClass) is not assignable from the candidate type's raw class (candidateClass) — the coder provably cannot encode values of that type. It throws IncompatibleCoderException which callers surface to users. This is the first, cheapest compatibility check before deeper generic-argument analysis.
Solutions
- Use a coder whose encoded type matches (or is a supertype of) the element type, e.g. StringUtf8Coder for String values.
- Fix a custom coder's getEncodedTypeDescriptor to return the correct TypeDescriptor.
- Register the coder for the correct type with registerCoderForType.
- Let the registry infer the coder instead of supplying one explicitly.
Example fix
// before
Coder<MyBase> coder = ...; // used for MySub that does not extend MyBase
// after
class MySubCoder extends CustomCoder<MySub> { ... } // encoded type MySub
Coder<MySub> coder = new MySubCoder(); Defensive patterns
Strategy: validation
Validate before calling
if (!coder.getEncodedTypeDescriptor().getRawType().isAssignableFrom(elementType)) {
throw new IllegalArgumentException("Coder " + coder + " cannot encode " + elementType);
} Type guard
static <T> boolean canEncode(Coder<?> coder, Class<T> type) {
return coder.getEncodedTypeDescriptor().getRawType().isAssignableFrom(type);
} Prevention
- Match coders to element types explicitly, not by position.
- Use well-known coders (StringUtf8Coder, VarIntCoder, etc.) for standard types.
- Check getEncodedTypeDescriptor when writing custom coders.
When it happens
Trigger: Any path through CoderRegistry.verifyCompatible — getDefaultCoders or recursive verification — where coder.getEncodedTypeDescriptor().getRawType() is not a supertype of the candidate type's raw class, e.g. verifying Coder<String> against type Integer.
Common situations: Passing the wrong Coder for a generic parameter; a custom coder that overrides getEncodedTypeDescriptor incorrectly; upstream code that changed a PCollection's element type but kept the old coder.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- cannot encode a null Instant
- cannot encode a null Iterable
- cannot encode a null
- cannot encode a null KV
- Cannot encode elements of type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/7e25bbc9232e6ea8.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderRegistry.java:537
Type codedType = codedDescriptor.getType();
// Various representations of the candidate type
@SuppressWarnings("unchecked")
TypeDescriptor<CandidateT> candidateDescriptor =
(TypeDescriptor<CandidateT>) TypeDescriptor.of(candidateType);
@SuppressWarnings("unchecked")
Class<CandidateT> candidateClass = (Class<CandidateT>) candidateDescriptor.getRawType();
// If coder has type Coder<T> where the actual value of T is lost
// to erasure, then we cannot rule it out.
if (candidateType instanceof TypeVariable) {
return;
}
// If the raw types are not compatible, we can certainly rule out
// coder compatibility
if (!codedClass.isAssignableFrom(candidateClass)) {
throw new IncompatibleCoderException(
String.format(
"Cannot encode elements of type %s with coder %s because the"
+ " coded type %s is not assignable from %s",
candidateType, coder, codedClass, candidateType),
coder,
candidateType);
}
// we have established that this is a covariant upcast... though
// coders are invariant, we are just checking one direction
@SuppressWarnings("unchecked")
TypeDescriptor<T> candidateOkDescriptor = (TypeDescriptor<T>) candidateDescriptor;
// If the coded type is a parameterized type where any of the actual
// type parameters are not compatible, then the whole thing is certainly not
// compatible.
if ((codedType instanceof ParameterizedType) && !isNullOrEmpty(coder.getCoderArguments())) {
ParameterizedType parameterizedSupertype =
(ParameterizedType) candidateOkDescriptor.getSupertype(codedClass).getType();View on GitHub (pinned to 12126d8942)