apache/kafka · error · java.lang.IllegalArgumentException
Topic partitions to assign to cannot have null or empty topi
Error message
Topic partitions to assign to cannot have null or empty topic
What it means
Thrown by KafkaConsumer.assign(Collection<TopicPartition>) when the passed collection is non-null and non-empty but contains a TopicPartition whose topic name is null, empty, or whitespace-only. The client validates every TopicPartition before publishing an AssignmentChangeEvent so the background network thread never has to deal with malformed partition metadata. It is a programmer error, not a transient runtime condition.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java:1902
}
@Override
public void assign(Collection<TopicPartition> partitions) {
acquireAndEnsureOpen();
try {
if (partitions == null) {
throw new IllegalArgumentException("Topic partitions collection to assign to cannot be null");
}
if (partitions.isEmpty()) {
unsubscribe();
return;
}
for (TopicPartition tp : partitions) {
String topic = (tp != null) ? tp.topic() : null;
if (isBlank(topic))
throw new IllegalArgumentException("Topic partitions to assign to cannot have null or empty topic");
}
// Clear the buffered data which are not a part of newly assigned topics
final Set<TopicPartition> currentTopicPartitions = new HashSet<>();
for (TopicPartition tp : subscriptions.assignedPartitions()) {
if (partitions.contains(tp))
currentTopicPartitions.add(tp);
}
fetchBuffer.retainAll(currentTopicPartitions);
// assignment change event will trigger autocommit if it is configured and the group id is specified. This is
// to make sure offsets of topic partitions the consumer is unsubscribing from are committed since there will
// be no following rebalance.
//
// See the ApplicationEventProcessor.process() method that handles this event for more detail.
applicationEventHandler.addAndGet(new AssignmentChangeEvent(View on GitHub (pinned to c31c9215e1)
Solutions
- Validate each topic name before building the TopicPartition: filter out null/blank strings or fail fast with a clear upstream error.
- Log the offending TopicPartition (toString) in a wrapping try/catch to identify which element is malformed.
- If the topic list comes from configuration, ensure the property is non-empty and trim whitespace before use.
- Add a unit test that asserts assign() receives only well-formed TopicPartition objects.
Example fix
// before
List<TopicPartition> parts = topics.stream()
.map(t -> new TopicPartition(t, 0))
.collect(Collectors.toList());
consumer.assign(parts);
// after
List<TopicPartition> parts = topics.stream()
.filter(t -> t != null && !t.trim().isEmpty())
.map(t -> new TopicPartition(t.trim(), 0))
.collect(Collectors.toList());
if (parts.isEmpty()) throw new IllegalArgumentException("no valid topics");
consumer.assign(parts); Defensive patterns
Strategy: validation
Validate before calling
// Before consumer.assign(partitions):
if (partitions == null) throw new IllegalArgumentException("partitions is null");
for (TopicPartition tp : partitions) {
if (tp == null || tp.topic() == null || tp.topic().trim().isEmpty()) {
throw new IllegalArgumentException("TopicPartition has null/blank topic: " + tp);
}
}
consumer.assign(partitions); Type guard
// Java: ensure every TopicPartition is well-formed
static boolean isWellFormed(TopicPartition tp) {
return tp != null && tp.topic() != null && !tp.topic().trim().isEmpty()
&& tp.partition() >= 0;
}
// filter: partitions.removeIf(tp -> !isWellFormed(tp)); Try / catch
// Not recommended: validate before assign() rather than catching.
// If unavoidable:
try {
consumer.assign(partitions);
} catch (IllegalArgumentException e) {
// log, drop offending TopicPartition, or fail-fast upstream
log.error("Invalid assignment", e);
throw e;
} Prevention
- Sanitize TopicPartition collections at the boundary where they are built (e.g. from config or external input).
- Never construct TopicPartition with a topic literal that could be null; use Constants.requireNonNull or Objects.requireNonNull on the topic name.
- If topics come from a dynamic source, validate them against an allow-list before building TopicPartition objects.
- Unit-test assignment code paths with null entries and blank topic names.
When it happens
Trigger: Calling consumer.assign(Arrays.asList(new TopicPartition(null, 0))), passing a TopicPartition built from an uninitialized String field, or building the collection from a stream/map that yields null or "" topic names. Any element where TopicPartition.topic() returns a blank string triggers it; a wholly null TopicPartition element also triggers it because tp.topic() would be reached only after the null check at line 1900.
Common situations: Topic name read from a misconfigured property file or environment variable that resolved to empty; deserializing partitions from JSON/YAML where a field was omitted; refactoring code that previously used String topic names and forgetting to populate the field; unit tests that construct TopicPartition placeholders.
Related errors
- RebalanceListener cannot be null
- Topic pattern to subscribe to cannot be null
- Topic pattern to subscribe to cannot be empty
- Topic partition collection to assign to cannot be null
- Topic partitions to assign to cannot have null or empty topi
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/a698524a2fb9d879.json.
Report an issue: GitHub.