apache/kafka · error · IllegalArgumentException
topicIdFutures and nameFutures cannot both be null.
Error message
topicIdFutures and nameFutures cannot both be null.
What it means
Thrown by the DescribeTopicsResult protected constructor when both topicIdFutures and nameFutures are null. The result must contain exactly one future map; providing neither makes it impossible to retrieve any topic descriptions.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/admin/DescribeTopicsResult.java:43
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
/**
* The result of the {@link KafkaAdminClient#describeTopics(Collection)} call.
*/
@InterfaceAudience.Public
public class DescribeTopicsResult {
private final Map<Uuid, KafkaFuture<TopicDescription>> topicIdFutures;
private final Map<String, KafkaFuture<TopicDescription>> nameFutures;
// VisibleForTesting
protected DescribeTopicsResult(Map<Uuid, KafkaFuture<TopicDescription>> topicIdFutures, Map<String, KafkaFuture<TopicDescription>> nameFutures) {
if (topicIdFutures != null && nameFutures != null)
throw new IllegalArgumentException("topicIdFutures and nameFutures cannot both be specified.");
if (topicIdFutures == null && nameFutures == null)
throw new IllegalArgumentException("topicIdFutures and nameFutures cannot both be null.");
this.topicIdFutures = topicIdFutures;
this.nameFutures = nameFutures;
}
static DescribeTopicsResult ofTopicIds(Map<Uuid, KafkaFuture<TopicDescription>> topicIdFutures) {
return new DescribeTopicsResult(topicIdFutures, null);
}
static DescribeTopicsResult ofTopicNames(Map<String, KafkaFuture<TopicDescription>> nameFutures) {
return new DescribeTopicsResult(null, nameFutures);
}
/**
* Use when {@link Admin#describeTopics(TopicCollection, DescribeTopicsOptions)} used a TopicIdCollection
*
* @return a map from topic IDs to futures which can be used to check the status of
* individual topics if the request used topic IDs, otherwise return null.
*/View on GitHub (pinned to 996fb4585a)
Solutions
- Use ofTopicIds / ofTopicNames to guarantee exactly one map is provided.
- In subclasses, assert that exactly one map is non-null before delegating to super.
- Review construction call sites to ensure the selection logic always yields one map.
Example fix
// before new DescribeTopicsResult(null, null); // after DescribeTopicsResult.ofTopicNames(nameMap);
Defensive patterns
Strategy: validation
Validate before calling
if ((idMap == null) == (nameMap == null)) {
throw new IllegalArgumentException("Exactly one of topicIdFutures/nameFutures required");
} Prevention
- Use the static factories to guarantee exactly one map is set.
- In subclasses, assert the either/or invariant.
- Audit construction paths so selection logic always yields one map.
When it happens
Trigger: Directly constructing DescribeTopicsResult (or subclass) with null for both future maps.
Common situations: A subclass or test path that conditionally selects a map but resolves to none, or a copy-paste error passing null for both arguments.
Related errors
- topicIdFutures and nameFutures cannot both be specified.
- topicIdFutures and nameFutures cannot both be null.
- topicIdFutures and nameFutures cannot both be specified.
- Partition {partition} was not included in the original reque
- Topic {topic} was not included in the original request
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/ceb6c357a2a8c86b.
Report an issue: GitHub.