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

  1. Pass a non-null Collection (use Collections.emptyList() if you genuinely have no partitions).
  2. Fix the upstream computation so the partition set is never null — return emptyList() instead.
  3. 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

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


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/e42e920ba66d37d6.json. Report an issue: GitHub.