{"record":{"id":"1f7d7585bd971657","repo":"apache/flink","slug":"unable-to-access-field-on-object","errorCode":null,"errorMessage":"Unable to access field {} on object {}","messagePattern":"Unable to access field (.+?) on object (.+?)","errorType":"exception","errorClass":"NullKeyFieldException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoComparator.java","lineNumber":194,"sourceCode":"\n    @SuppressWarnings({\"rawtypes\", \"unchecked\"})\n    @Override\n    public void getFlatComparator(List<TypeComparator> flatComparators) {\n        for (int i = 0; i < comparators.length; i++) {\n            if (comparators[i] instanceof CompositeTypeComparator) {\n                ((CompositeTypeComparator) comparators[i]).getFlatComparator(flatComparators);\n            } else {\n                flatComparators.add(comparators[i]);\n            }\n        }\n    }\n\n    /** This method is handling the IllegalAccess exceptions of Field.get() */\n    public final Object accessField(Field field, Object object) {\n        try {\n            object = field.get(object);\n        } catch (NullPointerException npex) {\n            throw new NullKeyFieldException(\n                    \"Unable to access field \" + field + \" on object \" + object);\n        } catch (IllegalAccessException iaex) {\n            throw new RuntimeException(\n                    \"This should not happen since we call setAccesssible(true) in the ctor.\"\n                            + \" fields: \"\n                            + field\n                            + \" obj: \"\n                            + object);\n        }\n        return object;\n    }\n\n    @Override\n    public int hash(T value) {\n        int i = 0;\n        int code = 0;\n        for (; i < this.keyFields.length; i++) {\n            code *= TupleComparatorBase.HASH_SALT[i & 0x1F];","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoComparator.java#L176-L212","documentation":"PojoComparator.accessField(field, object) wraps Field.get(object); a NullPointerException from reflection occurs when 'object' itself is null, and Flink surfaces it as NullKeyFieldException('Unable to access field ... on object null'). It means the POJO whose key field is being read is null.","triggerScenarios":"groupBy/join/sort on a POJO key where a record in the stream/state is null: hash(), setReference(), compare(), etc. dereference keyFields[i] on a null POJO via accessField and reflection throws NPE.","commonSituations":"A source emits null elements (e.g. deserialization failure mapped to null, flatMap returning null); nulls inside keyed state or co-group inputs where POJO comparators are applied; inner nulls are fine but the top-level record being null is not.","solutions":["Filter out null records before keyBy/groupBy: stream.filter(Objects::nonNull)","Fix the source/deserializer so it never emits null records (emit a Skip/retry or throw instead)","Wrap records in a non-null container type (e.g. Tuple2 or a custom wrapper) if null must be representable"],"exampleFix":"// before\nd stream\n  .keyBy(pojo -> pojo.getUserId())\n  ...\n\n// after\nd stream\n  .filter(Objects::nonNull)\n  .keyBy(pojo -> pojo.getUserId())\n  ...","handlingStrategy":"validation","validationCode":"// guard before keyBy/groupBy on POJOs\nd stream\n  .filter(Objects::nonNull)\n  .keyBy(...);","typeGuard":"static <T> boolean isUsableAsPojoKey(T record) {\n    return record != null;\n}","tryCatchPattern":"try {\n    comparator.hash(record);\n} catch (NullKeyFieldException e) {\n    // null record reached the comparator; upstream null leak\n    throw new IllegalArgumentException(\"Null record reached keyed operator\", e);\n}","preventionTips":["Never emit null top-level records from sources or flatMaps","Filter nulls before keyed/sorted operators","Represent absence with wrapper types instead of null records"],"tags":["pojo","comparator","null-record","keyed-stream"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}