apache/iceberg · error

Cannot determine comparator for type: + type

Error message

Cannot determine comparator for type: + type

What it means

Comparators.forType() builds a java.util.Comparator for a given Iceberg primitive type. Types not covered by its if/else chain (e.g. non-primitive/nested types passed directly) have no comparator defined, so the library throws UnsupportedOperationException. Comparators are only defined for primitive types; nested types must go through the comparator builder.

Solutions

  1. Pass a primitive type (use field.type().asPrimitiveType()) to forType
  2. Use Comparators.comparator(schema) builder for nested struct/list/map types instead of forType
  3. Upgrade Iceberg if the type is a newer spec type supported by a newer version

Example fix

// before
Comparator<T> c = Comparators.forType(structType);
// after
Comparator<T> c = Comparators.forType(field.type().asPrimitiveType());
Defensive patterns

Strategy: type-guard

Validate before calling

if (!type.isPrimitiveType()) throw new IllegalArgumentException("forType requires a primitive type: " + type);

Type guard

boolean hasComparator(Type t) { return t.isPrimitiveType(); }

Try / catch

try { cmp = Comparators.forType(type); } catch (UnsupportedOperationException e) { cmp = null; /* handle non-comparable type */ }

Prevention

When it happens

Trigger: Calling Comparators.forType(Types.NestedField.type()) or forType with a StructType/ListType/MapType instead of a primitive type; passing an unknown or UNKNOWN type.

Common situations: Passing the whole field type instead of field.type().typeId()'s primitive; sorting/merging code hitting a newly added spec type (e.g. geometry/geography) on an older client version.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/32ae20261849e0a6. Report an issue: GitHub.

Appendix: source

Thrown at api/src/main/java/org/apache/iceberg/types/Comparators.java:77

    return new ListComparator<>(list);
  }

  public static <K, V> Comparator<Map<K, V>> forType(Types.MapType mapType) {
    return new MapComparator<>(mapType);
  }

  @SuppressWarnings("unchecked")
  public static <T> Comparator<T> forType(Type.PrimitiveType type) {
    Comparator<?> cmp = COMPARATORS.get(type);
    if (cmp != null) {
      return (Comparator<T>) cmp;
    } else if (type instanceof Types.FixedType) {
      return (Comparator<T>) Comparators.unsignedBytes();
    } else if (type instanceof Types.DecimalType) {
      return (Comparator<T>) Comparator.naturalOrder();
    }

    throw new UnsupportedOperationException("Cannot determine comparator for type: " + type);
  }

  @SuppressWarnings("unchecked")
  private static <T> Comparator<T> internal(Type type) {
    if (type.isPrimitiveType()) {
      return forType(type.asPrimitiveType());
    } else if (type.isStructType()) {
      return (Comparator<T>) forType(type.asStructType());
    } else if (type.isListType()) {
      return (Comparator<T>) forType(type.asListType());
    } else if (type.isMapType()) {
      return (Comparator<T>) forType(type.asMapType());
    }

    throw new UnsupportedOperationException("Cannot determine comparator for type: " + type);
  }

  private static class StructLikeComparator implements Comparator<StructLike> {

View on GitHub (pinned to 86d9c8fc54)