{"id":"fd43c79dce3afaf8","repo":"apache/kafka","slug":"rebalancelistener-cannot-be-null","errorCode":null,"errorMessage":"RebalanceListener cannot be null","messagePattern":"RebalanceListener cannot be null","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java","lineNumber":2159,"sourceCode":"                return false;\n            } finally {\n                timer.update();\n            }\n        }\n        processBackgroundEvents();\n\n        return updateFetchPositions(timer);\n    }\n\n    @Override\n    public void subscribe(Collection<String> topics) {\n        subscribeInternal(topics, Optional.empty());\n    }\n\n    @Override\n    public void subscribe(Collection<String> topics, ConsumerRebalanceListener listener) {\n        if (listener == null)\n            throw new IllegalArgumentException(\"RebalanceListener cannot be null\");\n\n        subscribeInternal(topics, Optional.of(listener));\n    }\n\n    public void subscribe(Collection<String> topics, StreamsRebalanceListener streamsRebalanceListener) {\n\n        streamsRebalanceListenerInvoker\n            .orElseThrow(() -> new IllegalStateException(\"Consumer was not created to be used with Streams rebalance protocol events\"))\n            .setRebalanceListener(streamsRebalanceListener);\n\n        subscribeInternal(topics, Optional.empty());\n    }\n\n    @Override\n    public void subscribe(Pattern pattern) {\n        subscribeInternal(pattern, Optional.empty());\n    }\n","sourceCodeStart":2141,"sourceCodeEnd":2177,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java#L2141-L2177","documentation":"Thrown by KafkaConsumer.subscribe(Collection<String> topics, ConsumerRebalanceListener listener) when listener is null. The explicit-overload contract requires a non-null rebalance listener; passing null indicates the caller picked the wrong overload rather than intending 'no listener'. The client refuses to silently substitute a no-op listener so the API misuse surfaces immediately.","triggerScenarios":"Calling consumer.subscribe(topics, null) where the second argument is a literal null, a field that was never initialized, or the result of a helper that returned null on a missing config. Distinguishes from subscribe(Collection) which intentionally omits the listener.","commonSituations":"Refactoring code that conditionally supplied a listener and the conditional evaluated to null; DI frameworks injecting null when the bean was missing; copy-paste from a tutorial that used the single-arg overload but the developer added a null second argument; mock objects in tests returning null.","solutions":["If you do not need rebalance callbacks, call the single-argument overload consumer.subscribe(topics) instead.","If you do need callbacks, pass a concrete ConsumerRebalanceListener implementation (even a no-op one with empty methods).","Audit the source of the listener variable; ensure the field or factory method can never return null.","Add @NonNull annotations (JSR-305/SpotBugs) so static analysis catches null at compile time."],"exampleFix":"// before\nConsumerRebalanceListener listener = config.isRebalanceEnabled() ? new MyListener() : null;\nconsumer.subscribe(topics, listener);\n\n// after\nif (config.isRebalanceEnabled()) {\n    consumer.subscribe(topics, new MyListener());\n} else {\n    consumer.subscribe(topics); // overload without listener\n}","handlingStrategy":"validation","validationCode":"// Before consumer.subscribe(topics, listener):\nif (listener == null) throw new IllegalArgumentException(\"listener must not be null\");\n// or supply a no-op default:\nConsumerRebalanceListener safe = (listener != null) ? listener : new ConsumerRebalanceListener() {\n    public void onPartitionsRevoked(Collection<TopicPartition> p) {}\n    public void onPartitionsAssigned(Collection<TopicPartition> p) {}\n};\nconsumer.subscribe(topics, safe);","typeGuard":"static boolean isRebalanceListener(Object o) {\n    return o instanceof ConsumerRebalanceListener;\n}","tryCatchPattern":"// Prefer pre-validation. Catch only as a safety net:\ntry {\n    consumer.subscribe(topics, listener);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"RebalanceListener\")) {\n        log.warn(\"Null listener; falling back to no-op\", e);\n        consumer.subscribe(topics); // variant without listener\n    } else throw e;\n}","preventionTips":["Treat ConsumerRebalanceListener as a required dependency of subscribe(topics, listener); enforce with Objects.requireNonNull(listener).","Keep listener construction in a factory method that never returns null.","If you do not need callbacks, call the subscribe(topics) overload instead of passing null."],"tags":["consumer","subscribe","rebalance-listener","validation","illegal-argument","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}