{"id":"1145e28d098fdc83","repo":"apache/kafka","slug":"partition-partition-was-not-included-in-the-orig","errorCode":null,"errorMessage":"Partition {partition} was not included in the original request","messagePattern":"Partition (.+?) was not included in the original request","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"clients/src/main/java/org/apache/kafka/clients/admin/DeleteConsumerGroupOffsetsResult.java","lineNumber":47,"sourceCode":" * The result of the {@link Admin#deleteConsumerGroupOffsets(String, Set)} call.\n */\n@InterfaceAudience.Public\npublic class DeleteConsumerGroupOffsetsResult {\n    private final KafkaFuture<Map<TopicPartition, Errors>> future;\n    private final Set<TopicPartition> partitions;\n\n\n    DeleteConsumerGroupOffsetsResult(KafkaFuture<Map<TopicPartition, Errors>> future, Set<TopicPartition> partitions) {\n        this.future = future;\n        this.partitions = partitions;\n    }\n\n    /**\n     * Return a future which can be used to check the result for a given partition.\n     */\n    public KafkaFuture<Void> partitionResult(final TopicPartition partition) {\n        if (!partitions.contains(partition)) {\n            throw new IllegalArgumentException(\"Partition \" + partition + \" was not included in the original request\");\n        }\n        final KafkaFutureImpl<Void> result = new KafkaFutureImpl<>();\n\n        this.future.whenComplete((topicPartitions, throwable) -> {\n            if (throwable != null) {\n                result.completeExceptionally(throwable);\n            } else if (!maybeCompleteExceptionally(topicPartitions, partition, result)) {\n                result.complete(null);\n            }\n        });\n        return result;\n    }\n\n    /**\n     * Return a future which succeeds only if all the deletions succeed.\n     * If not, the first partition error shall be returned.\n     */\n    public KafkaFuture<Void> all() {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/admin/DeleteConsumerGroupOffsetsResult.java#L29-L65","documentation":"Thrown by DeleteConsumerGroupOffsetsResult.partitionResult when the caller asks for the per-partition result of a partition that was not in the original Admin.deleteConsumerGroupOffsets request set. The result object only tracks partitions the user originally passed; asking for any other TopicPartition is a programming error and is rejected immediately (IllegalArgumentException) rather than via the future.","triggerScenarios":"Calling result.partitionResult(tp) with a TopicPartition that is not equal (topic+partition) to one of the entries in the Set<TopicPartition> passed to Admin.deleteConsumerGroupOffsets. Typical when the caller builds the partition set and the lookup key from different sources, or mutates the set between request and result lookup.","commonSituations":"Stale references (request was built from one partition list, lookup uses another); copying example code and forgetting to substitute the actual request set; off-by-one in partition numbering; using a TopicPartition object whose topic string case differs from the request.","solutions":["Pass the exact same TopicPartition object (or an equal topic+partition) that you included in the original deleteConsumerGroupOffsets call.","Iterate over the original partition set instead of constructing new TopicPartition instances for lookup.","Re-issue Admin.deleteConsumerGroupOffsets with the full set of partitions you intend to query.","Verify topic name spelling, casing, and partition index before lookup."],"exampleFix":"// before\nSet<TopicPartition> req = Set.of(new TopicPartition(\"orders\", 0));\nDeleteConsumerGroupOffsetsResult r =\n    admin.deleteConsumerGroupOffsets(\"grp\", req);\nr.partitionResult(new TopicPartition(\"orders\", 1)).get(); // not in set\n\n// after - lookup only partitions present in the request set\nfor (TopicPartition tp : req) {\n    r.partitionResult(tp).get();\n}","handlingStrategy":"validation","validationCode":"// Keep the exact Set<TopicPartition> handed to deleteConsumerGroupOffsets and\n// only query partitionResult(...) for members of that set.\nSet<TopicPartition> requested = Set.of(\n    new TopicPartition(\"orders\", 0),\n    new TopicPartition(\"orders\", 1));\nDeleteConsumerGroupOffsetsResult result =\n    admin.deleteConsumerGroupOffsets(groupId, requested);\n\nTopicPartition query = new TopicPartition(\"orders\", 0);\nif (requested.contains(query)) {\n    result.partitionResult(query).get();\n} else {\n    log.warn(\"{} was not part of the delete request; skipping\", query);\n}","typeGuard":null,"tryCatchPattern":"// Note: the exception is thrown SYNCHRONOUSLY by partitionResult(...), not via the future.\ntry {\n    result.partitionResult(tp).get();\n} catch (IllegalArgumentException e) {\n    // `tp` was not in the set passed to deleteConsumerGroupOffsets.\n    // Either reuse the original set, or drop this partition from processing.\n    log.warn(\"Skipping {}: {}\", tp, e.getMessage());\n}","preventionTips":["Store the Set<TopicPartition> passed to Admin.deleteConsumerGroupOffsets and iterate over it when collecting per-partition results.","Do not reconstruct TopicPartition objects from external/untrusted input and feed them to partitionResult without a contains() check.","When you only need an aggregate outcome, call result.all() instead of partitionResult(...) per partition.","Treat the request set as the source of truth: derive every partitionResult query from it, not from a parallel data structure."],"tags":["admin-client","consumer-groups","api-misuse","illegal-argument","request-set"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}