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 DeleteTopicsResult protected constructor when both topicIdFutures and nameFutures are null. The result must carry exactly one future map; supplying neither leaves the object in an unusable state with no way to look up results.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java:40
import org.apache.kafka.common.Uuid;
import org.apache.kafka.common.annotation.InterfaceAudience;
import java.util.Collection;
import java.util.Map;
/**
* The result of the {@link Admin#deleteTopics(Collection)} call.
*/
@InterfaceAudience.Public
public class DeleteTopicsResult {
private final Map<Uuid, KafkaFuture<Void>> topicIdFutures;
private final Map<String, KafkaFuture<Void>> nameFutures;
protected DeleteTopicsResult(Map<Uuid, KafkaFuture<Void>> topicIdFutures, Map<String, KafkaFuture<Void>> 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 DeleteTopicsResult ofTopicIds(Map<Uuid, KafkaFuture<Void>> topicIdFutures) {
return new DeleteTopicsResult(topicIdFutures, null);
}
static DeleteTopicsResult ofTopicNames(Map<String, KafkaFuture<Void>> nameFutures) {
return new DeleteTopicsResult(null, nameFutures);
}
/**
* Use when {@link Admin#deleteTopics(TopicCollection, DeleteTopicsOptions)} used a TopicIdCollection
* @return a map from topic IDs to futures which can be used to check the status of
* individual deletions if the deleteTopics request used topic IDs. Otherwise return null.
*/
public Map<Uuid, KafkaFuture<Void>> topicIdValues() {View on GitHub (pinned to 996fb4585a)
Solutions
- Use the static factories ofTopicIds / ofTopicNames to guarantee exactly one map is set.
- If subclassing, ensure exactly one of the two maps is always provided.
- Add constructor assertions in subclasses to fail fast with a clearer message.
Example fix
// before new DeleteTopicsResult(null, null); // after DeleteTopicsResult.ofTopicNames(nameMap);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure exactly one map is non-null
if ((idMap == null) == (nameMap == null)) {
throw new IllegalArgumentException("Exactly one of topicIdFutures/nameFutures required");
} Prevention
- Use the static factories to avoid passing null/null.
- In subclass constructors, assert exactly one map is provided.
- Review conditional map-selection logic to guarantee one branch is taken.
When it happens
Trigger: Directly instantiating DeleteTopicsResult (or subclass) with null for both the topicIdFutures and nameFutures arguments.
Common situations: Subclass or test code mistakenly passes null/null, or a code path that conditionally builds both maps but ends up selecting neither.
Related errors
- topicIdFutures and nameFutures cannot both be specified.
- topicIdFutures and nameFutures cannot both be specified.
- topicIdFutures and nameFutures cannot both be null.
- 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/1366c25090e2f210.
Report an issue: GitHub.