apache/kafka · error · IllegalArgumentException

List Offsets for partition

Error message

List Offsets for partition "{partition}" was not attempted

What it means

An IllegalArgumentException thrown by ListOffsetsResult.partitionResult(TopicPartition) when the given partition was not part of the original listOffsets request. The result only contains futures for partitions you asked about; any other partition is a caller bug.

Solutions

  1. Iterate the exact keyset of the Map passed to listOffsets when calling partitionResult.
  2. Cache the requested Map<TopicPartition, OffsetSpec> and reuse its keys for result access.
  3. Use result.all() when you do not need per-partition accessor semantics.

Example fix

// before
Map<TopicPartition, OffsetSpec> req = ...;
ListOffsetsResult r = admin.listOffsets(req);
r.partitionResult(new TopicPartition("otherTopic", 0));

// after
for (TopicPartition tp : req.keySet()) {
    r.partitionResult(tp);
}
Defensive patterns

Strategy: validation

Validate before calling

Map<TopicPartition, OffsetSpec> request = ...;
ListOffsetsResult r = admin.listOffsets(request);
for (TopicPartition tp : request.keySet()) r.partitionResult(tp);

Type guard

static boolean wasRequested(TopicPartition tp, Set<TopicPartition> requested) {
    return requested.contains(tp);
}

Prevention

When it happens

Trigger: Calling Admin.listOffsets(Map<TopicPartition, ...>) with a set of partitions, then calling result.partitionResult(tp) for a TopicPartition that was not a key in that map. Constructing a TopicPartition with a different topic name or partition number than requested.

Common situations: Iterating a different (larger) partition set when reading results than was used for the request; off-by-one in partition numbering; race conditions where the requested map is mutated between request and result handling.

Related errors


AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11). Data as JSON: /api/errors/2e207ba7a5c97f87. Report an issue: GitHub.

Appendix: source

Thrown at clients/src/main/java/org/apache/kafka/clients/admin/ListOffsetsResult.java:47

/**
 * The result of the {@link AdminClient#listOffsets(Map)} call.
 */
@InterfaceAudience.Public
public class ListOffsetsResult {

    private final Map<TopicPartition, KafkaFuture<ListOffsetsResultInfo>> futures;

    public ListOffsetsResult(Map<TopicPartition, KafkaFuture<ListOffsetsResultInfo>> futures) {
        this.futures = futures;
    }

    /**
    * Return a future which can be used to check the result for a given partition.
    */
    public KafkaFuture<ListOffsetsResultInfo> partitionResult(final TopicPartition partition) {
        KafkaFuture<ListOffsetsResultInfo> future = futures.get(partition);
        if (future == null) {
            throw new IllegalArgumentException(
                    "List Offsets for partition \"" + partition + "\" was not attempted");
        }
        return future;
    }

    /**
     * Return a future which succeeds only if offsets for all specified partitions have been successfully
     * retrieved.
     */
    public KafkaFuture<Map<TopicPartition, ListOffsetsResultInfo>> all() {
        return KafkaFuture.allOf(futures.values().toArray(new KafkaFuture<?>[0]))
                .thenApply(v -> {
                    Map<TopicPartition, ListOffsetsResultInfo> offsets = new HashMap<>(futures.size());
                    for (Map.Entry<TopicPartition, KafkaFuture<ListOffsetsResultInfo>> entry : futures.entrySet()) {
                        try {
                            offsets.put(entry.getKey(), entry.getValue().get());
                        } catch (InterruptedException | ExecutionException e) {
                            // This should be unreachable, because allOf ensured that all the futures completed successfully.

View on GitHub (pinned to 996fb4585a)