apache/kafka · error · IllegalArgumentException
Offsets for consumer group '{groupId}' were not requested.
Error message
Offsets for consumer group '{groupId}' were not requested. What it means
Thrown by ListConsumerGroupOffsetsResult.partitionsToOffsetAndMetadata(groupId) when the requested groupId was not part of the original listConsumerGroupOffsets request. The Admin client builds a future per requested group; asking for a group that was not requested is a programming error caught client-side before any broker interaction.
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 c31c9215e1)
Solutions
- Ensure the groupId passed to partitionsToOffsetAndMetadata exactly matches one of the keys used in the listConsumerGroupOffsets request
- If you requested multiple groups, iterate the result of all() or pass each requested key individually instead of guessing
- Use partitionsToOffsetAndMetadata() (no-arg) only when exactly one group was requested; otherwise pass the specific group id
Example fix
// before
ListConsumerGroupOffsetsResult r = admin.listConsumerGroupOffsets(Map.of("g1", opts));
r.partitionsToOffsetAndMetadata("g2"); // throws
// after
r.partitionsToOffsetAndMetadata("g1");
// or, for multiple groups:
r.all().get().forEach((g, m) -> process(g, m)); Defensive patterns
Strategy: validation
Validate before calling
// Track the groupIds you passed to listConsumerGroupOffsets up front.
Set<String> requestedGroupIds = new HashSet<>(groupIds); // the set given to admin.listConsumerGroupOffsets(...)
String groupId = ...;
if (!requestedGroupIds.contains(groupId)) {
// caller bug: this group was not part of the request; handle/log and skip
return;
}
ListConsumerGroupOffsetsResult result = admin.listConsumerGroupOffsets(requestedGroupIds);
result.partitionsToOffsetAndMetadata(groupId).get(); Type guard
// Narrow a request key to one actually present in the requested set.
static Optional<String> requestedGroup(Set<String> requested, String groupId) {
return groupId != null && requested.contains(groupId) ? Optional.of(groupId) : Optional.empty();
} Try / catch
try {
result.partitionsToOffsetAndMetadata(groupId).get();
} catch (IllegalArgumentException e) {
// groupId was not in the original listConsumerGroupOffsets request set;
// fix the caller's bookkeeping rather than retrying.
log.warn("Skipping group {} - not part of listConsumerGroupOffsets request", groupId);
} Prevention
- Keep the exact Set<String> of groupIds passed to listConsumerGroupOffsets and only query those keys on the result.
- When a single group is requested, prefer partitionsToOffsetAndMetadata() (no-arg) which only works when futures.size()==1.
- Treat this exception as a programming error, not a transient failure - never retry with the same arguments.
When it happens
Trigger: Calling result.partitionsToOffsetAndMetadata("g2") after Admin.listConsumerGroupOffsets was invoked with a different group (e.g. "g1" or a Map that did not include "g2"). Also happens when a typo or stale variable is passed as the groupId, or when the multi-group listConsumerGroupOffsets(Map) overload is used but the per-group accessor is called with a key not in that map.
Common situations: Refactoring code from single-group to multi-group listing and forgetting to update the accessor call; passing a group id loaded from a different config key than the one used in the request; copy-paste between services where the requested set and the queried set drift apart.
Related errors
- List Offsets for partition "{partition}" was not attempted
- Group ID not found: {groupId}
- Invalid empty members has been provided
- The method: memberResult is not applicable in 'removeAll' mo
- Cannot create a new partition reassignment without any repli
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/0881a3c79078d32b.json.
Report an issue: GitHub.