apache/flink · error · UnsupportedOperationException

Record deserialization with leading normalized keys not supp

Error message

Record deserialization with leading normalized keys not supported.

What it means

NullAwareComparator.readWithKeyDenormalization() always throws UnsupportedOperationException, mirroring writeWithKeyNormalization: the wrapper cannot participate in the key-normalized serialization protocol because its null flag lives outside the wrapped comparator's normalized form.

Source

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

            }
            // write a non-null byte with key
            else {
                target.putBoolean(offset, true);
                // write key
                wrappedComparator.putNormalizedKey(record, target, offset + 1, numBytes - 1);
            }
        }
    }

    @Override
    public void writeWithKeyNormalization(T record, DataOutputView target) throws IOException {
        throw new UnsupportedOperationException(
                "Record serialization with leading normalized keys not supported.");
    }

    @Override
    public T readWithKeyDenormalization(T reuse, DataInputView source) throws IOException {
        throw new UnsupportedOperationException(
                "Record deserialization with leading normalized keys not supported.");
    }

    @Override
    public boolean invertNormalizedKey() {
        return wrappedComparator.invertNormalizedKey();
    }

    @Override
    public TypeComparator<T> duplicate() {
        return new NullAwareComparator<T>(wrappedComparator.duplicate(), order);
    }

    @Override
    public int extractKeys(Object record, Object[] target, int index) {
        if (record == null) {
            for (int i = 0; i < flatFields; i++) {
                target[index + i] = null;

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Gate key-normalized serialization on supportsSerializationWithKeyNormalization() for both write and read sides
  2. Use plain serializer.deserialize/reuse-based deserialization for null-nullable fields
  3. Handle nullability at the composite (Row) level rather than on field comparators

Example fix

// before
T v = comparator.readWithKeyDenormalization(reuse, source);

// after
T v = comparator.supportsSerializationWithKeyNormalization()
    ? comparator.readWithKeyDenormalization(reuse, source)
    : serializer.deserialize(reuse, source);
Defensive patterns

Strategy: validation

Validate before calling

if (!comparator.supportsSerializationWithKeyNormalization()) {
    return serializer.deserialize(reuse, source); // plain path
}
return comparator.readWithKeyDenormalization(reuse, source);

Prevention

When it happens

Trigger: A deserialization path pairing readWithKeyDenormalization with normalized-key reading invokes it on a NullAwareComparator field; should never be reached if the caller honored supportsSerializationWithKeyNormalization() == false.

Common situations: Custom operators or extension code that implements one half of the protocol (write) and assumes the read half exists; version upgrades where a path newly opts into key-normalized serialization.

Related errors


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