apache/kafka · error · IllegalArgumentException

Offsets for consumer group

Error message

Offsets for consumer group '{groupId}' were not requested.

What it means

An IllegalArgumentException thrown by ListConsumerGroupOffsetsResult.partitionsToOffsetAndMetadata(groupId) when the supplied groupId was not among the groups requested in the original listConsumerGroupOffsets call. The result object only carries futures for the groups you asked about.

Solutions

  1. Only query for groupIds you passed into the listConsumerGroupOffsets request.
  2. Keep the requested set in a variable and iterate it when reading per-group futures.
  3. Trim/normalize groupId strings before both requesting and querying.

Example fix

// before
ListConsumerGroupOffsetsResult r = admin.listConsumerGroupOffsets(Set.of("g1","g2"));
r.partitionsToOffsetAndMetadata("g3"); // not requested

// after
r.partitionsToOffsetAndMetadata("g1");
Defensive patterns

Strategy: validation

Validate before calling

Set<String> requested = Set.copyOf(groupIds);
ListConsumerGroupOffsetsResult r = admin.listConsumerGroupOffsets(requested);
for (String g : requested) r.partitionsToOffsetAndMetadata(g);

Type guard

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

Prevention

When it happens

Trigger: Listing offsets for a set of groups, then calling partitionsToOffsetAndMetadata with a groupId that was not in that set. Case/whitespace mismatch between the requested id and the queried id.

Common situations: Building the requested set from one source and querying from another; typos in the group id; trailing whitespace from user input; reusing a stale groupId after the requested set changed.

Related errors


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

Appendix: source

Thrown at clients/src/main/java/org/apache/kafka/clients/admin/ListConsumerGroupOffsetsResult.java:66

     * Return a future which yields a map of topic partitions to OffsetAndMetadata objects.
     * If the group does not have a committed offset for this partition, the corresponding value in the returned map will be null.
     */
    public KafkaFuture<Map<TopicPartition, OffsetAndMetadata>> partitionsToOffsetAndMetadata() {
        if (futures.size() != 1) {
            throw new IllegalStateException("Offsets from multiple consumer groups were requested. " +
                    "Use partitionsToOffsetAndMetadata(groupId) instead to get future for a specific group.");
        }
        return futures.values().iterator().next();
    }

    /**
     * Return a future which yields a map of topic partitions to OffsetAndMetadata objects for
     * the specified group. If the group doesn't have a committed offset for a specific
     * partition, the corresponding value in the returned map will be null.
     */
    public KafkaFuture<Map<TopicPartition, OffsetAndMetadata>> partitionsToOffsetAndMetadata(String groupId) {
        if (!futures.containsKey(groupId))
            throw new IllegalArgumentException("Offsets for consumer group '" + groupId + "' were not requested.");
        return futures.get(groupId);
    }

    /**
     * Return a future which yields all {@code Map<String, Map<TopicPartition, OffsetAndMetadata>} objects,
     * if requests for all the groups succeed.
     */
    public KafkaFuture<Map<String, Map<TopicPartition, OffsetAndMetadata>>> all() {
        return KafkaFuture.allOf(futures.values().toArray(new KafkaFuture<?>[0])).thenApply(
            nil -> {
                Map<String, Map<TopicPartition, OffsetAndMetadata>> listedConsumerGroupOffsets = new HashMap<>(futures.size());
                futures.forEach((key, future) -> {
                    try {
                        listedConsumerGroupOffsets.put(key, future.get());
                    } catch (InterruptedException | ExecutionException e) {
                        // This should be unreachable, since the KafkaFuture#allOf already ensured
                        // that all of the futures completed successfully.
                        throw new RuntimeException(e);

View on GitHub (pinned to 996fb4585a)