apache/flink · error · UnsupportedOperationException

Cannot create Comparator for

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.

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.

Appendix: 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)