apache/flink · error · UnsupportedOperationException

Cannot create Comparator for {typeClass.getCanonicalName()}.

Error message

Cannot create Comparator for {typeClass.getCanonicalName()}. Class does not implement Comparable interface.

What it means

Thrown by WritableTypeInfo.createComparator() when the Writable type does not also implement java.lang.Comparable. Flink can only build a TypeComparator (needed for grouping/sorting/keyed state) for Writable types that are Comparable; otherwise no ordering exists and createComparator refuses with UnsupportedOperationException. The message reports the offending type's canonical name.

Source

Thrown at flink-connectors/flink-hadoop-compatibility/src/main/java/org/apache/flink/api/java/typeutils/WritableTypeInfo.java:70

    @PublicEvolving
    public WritableTypeInfo(Class<T> typeClass) {
        this.typeClass = checkNotNull(typeClass);

        checkArgument(
                Writable.class.isAssignableFrom(typeClass) && !typeClass.equals(Writable.class),
                "WritableTypeInfo can only be used for subclasses of %s",
                Writable.class.getName());
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    @PublicEvolving
    public TypeComparator<T> createComparator(
            boolean sortOrderAscending, ExecutionConfig executionConfig) {
        if (Comparable.class.isAssignableFrom(typeClass)) {
            return new WritableComparator(sortOrderAscending, typeClass);
        } else {
            throw new UnsupportedOperationException(
                    "Cannot create Comparator for "
                            + typeClass.getCanonicalName()
                            + ". "
                            + "Class does not implement Comparable interface.");
        }
    }

    @Override
    @PublicEvolving
    public boolean isBasicType() {
        return false;
    }

    @Override
    @PublicEvolving
    public boolean isTupleType() {
        return false;
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Make the Writable key class implement java.lang.Comparable (and ideally also WritableComparable), supplying a consistent ordering.
  2. If the Writable cannot be made Comparable, key/group on a different (comparable) field instead.
  3. Provide an explicit KeySelector that extracts a comparable key rather than using the whole Writable object as the key.
  4. Verify isKeyType() (which checks Comparable) on the WritableTypeInfo before using the type as a key.

Example fix

// before — Writable used as key, not Comparable
public class MyWritable implements Writable { ... }
ds.keyBy(w -> w); // createComparator throws
// after — implement Comparable
public class MyWritable implements Writable, Comparable<MyWritable> {
    @Override public int compareTo(MyWritable o) { ... }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Before using a Writable as a key, check it is Comparable
Class<?> keyClass = myWritableKey.getClass();
if (!Comparable.class.isAssignableFrom(keyClass)) {
    throw new IllegalStateException(keyClass.getName()
        + " is not Comparable; cannot be used as a key. Implement Comparable/WritableComparable");
}

Type guard

Comparable.class.isAssignableFrom(myWritableKey.getClass())

Prevention

When it happens

Trigger: Produced when a Writable type is used as a key in a keyed/sorted/grouped operation (keyBy, groupBy, join/coGroup key, order-by, or any path that calls createComparator on its TypeInformation) and that Writable class does not implement Comparable — e.g. keying a stream by a Writable that lacks Comparable.

Common situations: Using a custom Writable as a key without implementing Comparable; keying by a Writable type that was only meant to be a value; calling distinct/groupBy/sort on a Writable field whose class is not Comparable; type extraction picking a Writable as the key type unexpectedly.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/9304e4a8f6212a70. Report an issue: GitHub.