apache/flink · error · RuntimeException

Comparator {} specifies an invalid length for the normalized

Error message

Comparator {} specifies an invalid length for the normalized key: {}

What it means

PojoComparator's constructor builds a normalized-key layout from its field comparators; if any comparator's getNormalizeKeyLen() returns a negative value, it throws this RuntimeException naming the offending comparator class. Negative means 'infinite/variable-length key' (e.g. String-type comparators before normalization support), which cannot fit the fixed normalized-key byte budget.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoComparator.java:106

                throw new IllegalArgumentException("One of the passed reflection fields is null");
            }

            // as long as the leading keys support normalized keys, we can build up the composite
            // key
            if (k.supportsNormalizedKey()) {
                if (i == 0) {
                    // the first comparator decides whether we need to invert the key direction
                    inverted = k.invertNormalizedKey();
                } else if (k.invertNormalizedKey() != inverted) {
                    // if a successor does not agree on the inversion direction, it cannot be part
                    // of the normalized key
                    break;
                }

                nKeys++;
                final int len = k.getNormalizeKeyLen();
                if (len < 0) {
                    throw new RuntimeException(
                            "Comparator "
                                    + k.getClass().getName()
                                    + " specifies an invalid length for the normalized key: "
                                    + len);
                }
                this.normalizedKeyLengths[i] = len;
                nKeyLen += this.normalizedKeyLengths[i];

                if (nKeyLen < 0) {
                    // overflow, which means we are out of budget for normalized key space anyways
                    nKeyLen = Integer.MAX_VALUE;
                    break;
                }
            } else {
                break;
            }
        }
        this.numLeadingNormalizableKeys = nKeys;

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. If writing a custom TypeComparator, implement getNormalizeKeyLen() to return the fixed normalized-key byte length (>= 0) when supportsNormalizedKey() is true
  2. Check the exception message: it names the exact comparator class to fix
  3. For String keys, use key types whose comparators support finite normalized keys, or upgrade Flink to a version where string comparators report a finite length

Example fix

// before (custom comparator)
@Override
public int getNormalizeKeyLen() {
    return -1; // infinite key -> PojoConstructor throws
}

// after
@Override
public int getNormalizeKeyLen() {
    return 8; // fixed normalized key length in bytes
}
Defensive patterns

Strategy: validation

Validate before calling

for (TypeComparator<?> c : fieldComparators) {
    if (c.supportsNormalizedKey() && c.getNormalizeKeyLen() < 0) {
        throw new IllegalStateException(
            c.getClass().getName() + " reports infinite normalized key length");
    }
}

Prevention

When it happens

Trigger: Constructing a PojoComparator whose key fields include a type whose comparator reports getNormalizeKeyLen() < 0 - typically string/byte-array keys in combinations that cannot be truncated into the normalized key - during sort/group operator setup.

Common situations: groupBy()/sortPartition() on a POJO field of String or similar variable-length type in older Flink versions where the comparator reported -1; custom TypeComparator implementations that forget to implement getNormalizeKeyLen() and return the default -1.

Related errors


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