apache/kafka · error · java.lang.IllegalArgumentException
Partitions collection cannot be null
Error message
Partitions collection cannot be null
What it means
IllegalArgumentException thrown at the entry of the private seek(Collection<TopicPartition>, AutoOffsetResetStrategy) helper that backs seekToBeginning/seekToEnd when the partitions argument is null. The guard runs before acquireAndEnsureOpen(); passing null is treated as a programming error because ResetOffsetEvent requires a concrete partition set. Note: an empty collection is allowed (the helper will still proceed), only null is rejected.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java:1212
));
} finally {
release();
}
}
@Override
public void seekToBeginning(Collection<TopicPartition> partitions) {
seek(partitions, AutoOffsetResetStrategy.EARLIEST);
}
@Override
public void seekToEnd(Collection<TopicPartition> partitions) {
seek(partitions, AutoOffsetResetStrategy.LATEST);
}
private void seek(Collection<TopicPartition> partitions, AutoOffsetResetStrategy offsetResetStrategy) {
if (partitions == null)
throw new IllegalArgumentException("Partitions collection cannot be null");
acquireAndEnsureOpen();
try {
applicationEventHandler.addAndGet(new ResetOffsetEvent(
partitions,
offsetResetStrategy,
defaultApiTimeoutDeadlineMs())
);
} finally {
release();
}
}
@Override
public long position(TopicPartition partition) {
return position(partition, defaultApiTimeoutMs);
}
View on GitHub (pinned to c31c9215e1)
Solutions
- Pass a non-null Collection (use Collections.emptyList() if you genuinely have no partitions).
- Fix the upstream computation so the partition set is never null — return emptyList() instead.
- Add a null-check at the call site and skip the seek call entirely when no partitions are available.
Example fix
// before Collection<TopicPartition> parts = lookupPartitions(topic); // may return null consumer.seekToBeginning(parts); // after Collection<TopicPartition> parts = lookupPartitions(topic); if (parts == null) parts = List.of(); if (!parts.isEmpty()) consumer.seekToBeginning(parts);
Defensive patterns
Strategy: type-guard
Validate before calling
// seekToBeginning/seekToEnd delegate to a private seek(Collection, ...) that
// rejects null. Validate (and normalize) the collection at the call site.
static java.util.Set<TopicPartition> requirePartitions(Collection<TopicPartition> parts) {
if (parts == null)
throw new IllegalArgumentException("partitions collection must not be null");
// Defensive copy also strips null elements which would otherwise NPE downstream.
java.util.Set<TopicPartition> out = new java.util.HashSet<>();
for (TopicPartition tp : parts) {
if (tp == null) throw new IllegalArgumentException("partitions contains a null element");
out.add(tp);
}
return java.util.Collections.unmodifiableSet(out);
}
// Usage:
// consumer.seekToBeginning(requirePartitions(assigned));
// consumer.seekToEnd(requirePartitions(assigned)); Type guard
// In Java prefer Collection<TopicPartition> from a trusted source (e.g. consumer.assignment())
// and wrap external input in a non-null factory (above).
//
// TypeScript analogue — make null impossible at the type level:
// type TopicPartition = { topic: string; partition: number };
// function seekToEnd(c: Consumer, parts: NonEmptyArray<TopicPartition>): void {
// // NonEmptyArray< T > = [T, ...T[]] — compiler rejects null/undefined/[]
// c.seekToEnd(parts);
// }
// // Caller must prove non-empty; the function body never sees null. Try / catch
// IllegalArgumentException here is purely a null-guard violation; surface it as a
// programming defect, never swallow.
try {
consumer.seekToEnd(partitions);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("cannot be null")) {
throw new IllegalStateException(
"Internal error: partitions collection passed to seekToEnd/seekToBeginning was null", e);
}
throw e;
} Prevention
- Always source the partitions argument from consumer.assignment() or a typed Set<TopicPartition> you control; avoid ad-hoc List literals built from user input.
- Wrap seekToBeginning/seekToEnd in a helper that produces an immutable, null-free set so the contract is enforced once, not at every call site.
- Enable static analysis (NullAway, Checker Framework, or IDE null inspections) to flag null collections before runtime.
- Treat 'cannot be null' exceptions as bugs in your own wiring, never as recoverable runtime errors.
When it happens
Trigger: Calling consumer.seekToBeginning(null) or consumer.seekToEnd(null). Also reachable via a wrapper/utility that passes through a null partition collection when the caller omitted it (e.g. seeking on a null topic partition set computed from an empty request).
Common situations: Code computes a partition set from a topic lookup that returned null instead of empty list; refactor that left a default-null parameter; tests calling seekToBeginning(null) by mistake; reactive wrapper that forwards null when upstream emits nothing.
Related errors
- seek offset must not be a negative number
- seek offset must not be a negative number
- Partitions collection cannot be null
- Topic cannot be null
- Headers cannot be null
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/e42e920ba66d37d6.json.
Report an issue: GitHub.