{"record":{"id":"ca384dc68dc11e3d","repo":"apache/flink","slug":"record-deserialization-with-leading-normalized-key","errorCode":null,"errorMessage":"Record deserialization with leading normalized keys not supported.","messagePattern":"Record deserialization with leading normalized keys not supported\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/NullAwareComparator.java","lineNumber":199,"sourceCode":"            }\n            // write a non-null byte with key\n            else {\n                target.putBoolean(offset, true);\n                // write key\n                wrappedComparator.putNormalizedKey(record, target, offset + 1, numBytes - 1);\n            }\n        }\n    }\n\n    @Override\n    public void writeWithKeyNormalization(T record, DataOutputView target) throws IOException {\n        throw new UnsupportedOperationException(\n                \"Record serialization with leading normalized keys not supported.\");\n    }\n\n    @Override\n    public T readWithKeyDenormalization(T reuse, DataInputView source) throws IOException {\n        throw new UnsupportedOperationException(\n                \"Record deserialization with leading normalized keys not supported.\");\n    }\n\n    @Override\n    public boolean invertNormalizedKey() {\n        return wrappedComparator.invertNormalizedKey();\n    }\n\n    @Override\n    public TypeComparator<T> duplicate() {\n        return new NullAwareComparator<T>(wrappedComparator.duplicate(), order);\n    }\n\n    @Override\n    public int extractKeys(Object record, Object[] target, int index) {\n        if (record == null) {\n            for (int i = 0; i < flatFields; i++) {\n                target[index + i] = null;","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/NullAwareComparator.java#L181-L217","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Gate key-normalized serialization on supportsSerializationWithKeyNormalization() for both write and read sides","Use plain serializer.deserialize/reuse-based deserialization for null-nullable fields","Handle nullability at the composite (Row) level rather than on field comparators"],"exampleFix":"// before\nT v = comparator.readWithKeyDenormalization(reuse, source);\n\n// after\nT v = comparator.supportsSerializationWithKeyNormalization()\n    ? comparator.readWithKeyDenormalization(reuse, source)\n    : serializer.deserialize(reuse, source);","handlingStrategy":"validation","validationCode":"if (!comparator.supportsSerializationWithKeyNormalization()) {\n    return serializer.deserialize(reuse, source); // plain path\n}\nreturn comparator.readWithKeyDenormalization(reuse, source);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mirror the feature probe on both write and read sides","Keep serializer and comparator capabilities in sync in custom operators"],"tags":["comparator","null-handling","normalized-key","unsupported-operation"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}