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

RowComparator.readWithKeyDenormalization() intentionally throws UnsupportedOperationException. It is the inverse of writeWithKeyNormalization(): the framework would call it to strip leading normalized key bytes during deserialization. Since Row does not embed normalized keys into its serialized form, this operation is unsupported by design.

Source

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

            TypeComparator<Object> comparator = comparators[i];
            Object element = record.getField(keyPositions[i]); // element can be null
            // write key
            comparator.putNormalizedKey(element, target, currentOffset, len);

            bytesLeft -= len;
            currentOffset += len;
        }
    }

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

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

    @Override
    public boolean invertNormalizedKey() {
        return invertNormKey;
    }

    @Override
    public TypeComparator<Row> duplicate() {
        NullAwareComparator<?>[] comparatorsCopy = new NullAwareComparator<?>[comparators.length];
        for (int i = 0; i < comparators.length; i++) {
            comparatorsCopy[i] = (NullAwareComparator<?>) comparators[i].duplicate();
        }

        TypeSerializer<?>[] serializersCopy = new TypeSerializer<?>[serializers.length];
        for (int i = 0; i < serializers.length; i++) {
            serializersCopy[i] = serializers[i].duplicate();

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Avoid Row as a keyed type in DataSet operators that require key-normalized serialization; use Tuple or POJO.
  2. Switch to the Table API / SQL which manages Row key comparison internally.
  3. Ensure the operator uses the plain serialize/deserialize path rather than key-normalized variants.

Example fix

// before — Row keyed in an operator that reads with key denormalization
DataSet<Row> rows = ...;
rows.groupBy(0).sortGroup(1, Order.ASCENDING); // may trigger readWithKeyDenormalization

// after — use a Tuple key to avoid the unsupported Row key-normalization path
DataSet<Tuple2<Integer, Row>> keyed =
    rows.map(r -> Tuple2.of((Integer) r.getField(0), r));
keyed.groupBy(0).sortGroup(1, Order.ASCENDING);
Defensive patterns

Strategy: fallback

Validate before calling

// Same as 669: readWithKeyDenormalization is unsupported for RowComparator.
// Avoid the code path entirely by not using Row as a key in DataSet
// operators that require key-normalized serialization.

Try / catch

// UnsupportedOperationException — no runtime recovery possible.
// Redesign the pipeline to avoid Row keys in DataSet key-normalized paths.

Prevention

When it happens

Trigger: A DataSet operator that wrote key-normalized records attempts to read them back through readWithKeyDenormalization(). For RowComparator this path does not exist, so the call fails immediately.

Common situations: Same as error 669: a DataSet pipeline using Row as a keyed type in an operator that expects key-normalized serialization/deserialization symmetry. This typically surfaces as the read-side counterpart of the same unsupported code path.

Related errors


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