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

  1. Use a coder whose encoded type matches (or is a supertype of) the element type, e.g. StringUtf8Coder for String values.
  2. Fix a custom coder's getEncodedTypeDescriptor to return the correct TypeDescriptor.
  3. Register the coder for the correct type with registerCoderForType.
  4. 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

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


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)