{"record":{"id":"85f84623b101b836","repo":"apache/kafka","slug":"offsets-from-multiple-consumer-groups-were-request","errorCode":null,"errorMessage":"Offsets from multiple consumer groups were requested. Use partitionsToOffsetAndMetadata(groupId) instead to get future for a specific group.","messagePattern":"Offsets from multiple consumer groups were requested\\. Use partitionsToOffsetAndMetadata\\(groupId\\) instead to get future for a specific group\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/admin/ListConsumerGroupOffsetsResult.java","lineNumber":53,"sourceCode":" * <p>\n */\n@InterfaceAudience.Public\npublic class ListConsumerGroupOffsetsResult {\n\n    final Map<String, KafkaFuture<Map<TopicPartition, OffsetAndMetadata>>> futures;\n\n    ListConsumerGroupOffsetsResult(final Map<CoordinatorKey, KafkaFuture<Map<TopicPartition, OffsetAndMetadata>>> futures) {\n        this.futures = futures.entrySet().stream()\n                .collect(Collectors.toMap(e -> e.getKey().idValue, Entry::getValue));\n    }\n\n    /**\n     * Return a future which yields a map of topic partitions to OffsetAndMetadata objects.\n     * If the group does not have a committed offset for this partition, the corresponding value in the returned map will be null.\n     */\n    public KafkaFuture<Map<TopicPartition, OffsetAndMetadata>> partitionsToOffsetAndMetadata() {\n        if (futures.size() != 1) {\n            throw new IllegalStateException(\"Offsets from multiple consumer groups were requested. \" +\n                    \"Use partitionsToOffsetAndMetadata(groupId) instead to get future for a specific group.\");\n        }\n        return futures.values().iterator().next();\n    }\n\n    /**\n     * Return a future which yields a map of topic partitions to OffsetAndMetadata objects for\n     * the specified group. If the group doesn't have a committed offset for a specific\n     * partition, the corresponding value in the returned map will be null.\n     */\n    public KafkaFuture<Map<TopicPartition, OffsetAndMetadata>> partitionsToOffsetAndMetadata(String groupId) {\n        if (!futures.containsKey(groupId))\n            throw new IllegalArgumentException(\"Offsets for consumer group '\" + groupId + \"' were not requested.\");\n        return futures.get(groupId);\n    }\n\n    /**\n     * Return a future which yields all {@code Map<String, Map<TopicPartition, OffsetAndMetadata>} objects,","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/clients/src/main/java/org/apache/kafka/clients/admin/ListConsumerGroupOffsetsResult.java#L35-L71","documentation":"An IllegalStateException thrown by ListConsumerGroupOffsetsResult.partitionsToOffsetAndMetadata() (the no-arg overload) when more than one consumer group was requested. The no-arg accessor assumes exactly one group; with multiple groups you must ask for each by id.","triggerScenarios":"Calling Admin.listConsumerGroupOffsets(Map<String, ListTopicsOptions>) with a map of size > 1, then calling result.partitionsToOffsetAndMetadata() (no arg). Also when the single-group overload was expected but the request was built with a multi-group API.","commonSituations":"Refactoring from listing one group to listing several but keeping the no-arg accessor; helper code that assumes single-group usage but is reused in a batch context.","solutions":["When listing multiple groups, call partitionsToOffsetAndMetadata(groupId) for each group, or use all() to get every group's offsets at once.","If you genuinely want a single group, use Admin.listConsumerGroupOffsets(String singleGroupId) instead of the Map overload."],"exampleFix":"// before\nMap<String, ListTopicsOptions> groups = Map.of(\"g1\", opts, \"g2\", opts);\nListConsumerGroupOffsetsResult r = admin.listConsumerGroupOffsets(groups);\nr.partitionsToOffsetAndMetadata(); // throws\n\n// after\nfor (String g : groups.keySet()) {\n    r.partitionsToOffsetAndMetadata(g);\n}","handlingStrategy":"validation","validationCode":"if (groupIds.size() == 1) {\n    result.partitionsToOffsetAndMetadata();\n} else {\n    for (String g : groupIds) result.partitionsToOffsetAndMetadata(g);\n}","typeGuard":"static boolean isSingleGroup(ListConsumerGroupOffsetsResult r) {\n    // heuristic: only call no-arg accessor when you know you requested one group\n    return requestedGroupIds.size() == 1;\n}","tryCatchPattern":null,"preventionTips":["Use the no-arg accessor only when you requested exactly one group.","For multi-group requests, iterate known ids or use all()."],"tags":["kafka-admin","consumer-groups","offsets","api-misuse","argument-validation"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}