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

  1. Use ofTopicIds / ofTopicNames to guarantee exactly one map is provided.
  2. In subclasses, assert that exactly one map is non-null before delegating to super.
  3. 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

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


AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11). Data as JSON: /api/errors/ceb6c357a2a8c86b. Report an issue: GitHub.