apache/kafka · error · java.lang.IllegalArgumentException
RebalanceListener cannot be null
Error message
RebalanceListener cannot be null
What it means
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.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java:2159
return false;
} finally {
timer.update();
}
}
processBackgroundEvents();
return updateFetchPositions(timer);
}
@Override
public void subscribe(Collection<String> topics) {
subscribeInternal(topics, Optional.empty());
}
@Override
public void subscribe(Collection<String> topics, ConsumerRebalanceListener listener) {
if (listener == null)
throw new IllegalArgumentException("RebalanceListener cannot be null");
subscribeInternal(topics, Optional.of(listener));
}
public void subscribe(Collection<String> topics, StreamsRebalanceListener streamsRebalanceListener) {
streamsRebalanceListenerInvoker
.orElseThrow(() -> new IllegalStateException("Consumer was not created to be used with Streams rebalance protocol events"))
.setRebalanceListener(streamsRebalanceListener);
subscribeInternal(topics, Optional.empty());
}
@Override
public void subscribe(Pattern pattern) {
subscribeInternal(pattern, Optional.empty());
}
View on GitHub (pinned to c31c9215e1)
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.
Example fix
// before
ConsumerRebalanceListener listener = config.isRebalanceEnabled() ? new MyListener() : null;
consumer.subscribe(topics, listener);
// after
if (config.isRebalanceEnabled()) {
consumer.subscribe(topics, new MyListener());
} else {
consumer.subscribe(topics); // overload without listener
} Defensive patterns
Strategy: validation
Validate before calling
// Before consumer.subscribe(topics, listener):
if (listener == null) throw new IllegalArgumentException("listener must not be null");
// or supply a no-op default:
ConsumerRebalanceListener safe = (listener != null) ? listener : new ConsumerRebalanceListener() {
public void onPartitionsRevoked(Collection<TopicPartition> p) {}
public void onPartitionsAssigned(Collection<TopicPartition> p) {}
};
consumer.subscribe(topics, safe); Type guard
static boolean isRebalanceListener(Object o) {
return o instanceof ConsumerRebalanceListener;
} Try / catch
// Prefer pre-validation. Catch only as a safety net:
try {
consumer.subscribe(topics, listener);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("RebalanceListener")) {
log.warn("Null listener; falling back to no-op", e);
consumer.subscribe(topics); // variant without listener
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Topic pattern to subscribe to cannot be null
- Topic pattern to subscribe to cannot be empty
- Topic partitions to assign to cannot have null or empty topi
- RebalanceListener cannot be null
- Topic collection to subscribe to cannot be null
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/fd43c79dce3afaf8.json.
Report an issue: GitHub.