apache/kafka · error · IllegalArgumentException
topicIdFutures and nameFutures cannot both be specified.
Error message
topicIdFutures and nameFutures cannot both be specified.
What it means
Thrown by the DeleteTopicsResult protected constructor when both topicIdFutures and nameFutures are non-null. The result object is designed to hold exactly one kind of future map — either by topic ID (Uuid) or by topic name — never both. Use the static factories ofTopicIds / ofTopicNames to construct correctly.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java:38
import org.apache.kafka.common.KafkaFuture;
import org.apache.kafka.common.TopicCollection;
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.View on GitHub (pinned to 996fb4585a)
Solutions
- Use DeleteTopicsResult.ofTopicIds(...) or ofTopicNames(...) instead of the constructor.
- If subclassing, pass null for the unused map parameter.
- Add a unit test verifying the subclass construction does not supply both maps.
Example fix
// before new DeleteTopicsResult(idMap, nameMap); // both non-null // after DeleteTopicsResult.ofTopicIds(idMap); // or DeleteTopicsResult.ofTopicNames(nameMap);
Defensive patterns
Strategy: validation
Validate before calling
// Always use the static factories; never pass both maps
DeleteTopicsResult result = useTopicIds
? DeleteTopicsResult.ofTopicIds(idMap)
: DeleteTopicsResult.ofTopicNames(nameMap); Prevention
- Never call the protected constructor directly; use ofTopicIds / ofTopicNames.
- In subclasses, enforce the either/or invariant before calling super.
- Add unit tests covering both single-map construction paths.
When it happens
Trigger: Directly instantiating DeleteTopicsResult (or a subclass constructor) with both the topicIdFutures map and nameFutures map non-null.
Common situations: A subclass or test code calls the protected constructor with both arguments, violating the either/or invariant. Normal usage goes through the static factory methods, so this is primarily a developer/extension error.
Related errors
- topicIdFutures and nameFutures cannot both be null.
- 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/50c309e21b5a1adb.
Report an issue: GitHub.