apache/kafka · error · IllegalArgumentException

The TopicCollection: {topics} provided did not match any sup

Error message

The TopicCollection: {topics} provided did not match any supported classes for deleteTopics.

What it means

Thrown by KafkaAdminClient.deleteTopics(TopicCollection, DeleteTopicsOptions) when the passed TopicCollection is neither a TopicIdCollection nor a TopicNameCollection. deleteTopics dispatches strictly on these two concrete subtypes (routing to handleDeleteTopicsUsingIds or handleDeleteTopicsUsingNames); any other implementation of TopicCollection is rejected immediately with IllegalArgumentException because there is no defined RPC mapping for it.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java:2010

                // If there were any topics retries due to a quota exceeded exception, we propagate
                // the initial error back to the caller if the request timed out.
                maybeCompleteQuotaExceededException(options.shouldRetryOnQuotaViolation(),
                    throwable, futures, quotaExceededExceptions, (int) (time.milliseconds() - now));
                // Fail all the other remaining futures
                completeAllExceptionally(futures.values(), throwable);
            }
        };
    }

    @Override
    public DeleteTopicsResult deleteTopics(final TopicCollection topics,
                                           final DeleteTopicsOptions options) {
        if (topics instanceof TopicIdCollection)
            return DeleteTopicsResult.ofTopicIds(handleDeleteTopicsUsingIds(((TopicIdCollection) topics).topicIds(), options));
        else if (topics instanceof TopicNameCollection)
            return DeleteTopicsResult.ofTopicNames(handleDeleteTopicsUsingNames(((TopicNameCollection) topics).topicNames(), options));
        else
            throw new IllegalArgumentException("The TopicCollection: " + topics + " provided did not match any supported classes for deleteTopics.");
    }

    private Map<String, KafkaFuture<Void>> handleDeleteTopicsUsingNames(final Collection<String> topicNames,
                                                                        final DeleteTopicsOptions options) {
        final Map<String, KafkaFutureImpl<Void>> topicFutures = new HashMap<>(topicNames.size());
        final List<String> validTopicNames = new ArrayList<>(topicNames.size());
        for (String topicName : topicNames) {
            if (topicNameIsUnrepresentable(topicName)) {
                KafkaFutureImpl<Void> future = new KafkaFutureImpl<>();
                future.completeExceptionally(new InvalidTopicException("The given topic name '" +
                    topicName + "' cannot be represented in a request."));
                topicFutures.put(topicName, future);
            } else if (!topicFutures.containsKey(topicName)) {
                topicFutures.put(topicName, new KafkaFutureImpl<>());
                validTopicNames.add(topicName);
            }
        }
        if (!validTopicNames.isEmpty()) {

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Use the provided factories: TopicCollection.ofTopicNames(names) or TopicCollection.ofTopicIds(ids) to build the collection, or call the convenience admin.deleteTopics(Collection<String>) / admin.deleteTopics(TopicIdCollection).
  2. If wrapping TopicCollection, extend TopicNameCollection or TopicIdCollection so the instanceof check succeeds.
  3. Avoid passing custom/reflectively-built TopicCollection objects to the overloaded deleteTopics(TopicCollection, DeleteTopicsOptions) method.

Example fix

// before - custom object, neither TopicIdCollection nor TopicNameCollection
admin.deleteTopics(myCustomTopicCollection, new DeleteTopicsOptions()); // throws

// after - use a supported collection
TopicCollection topics = TopicCollection.ofTopicNames(Arrays.asList("orders","shipments"));
admin.deleteTopics(topics, new DeleteTopicsOptions());
Defensive patterns

Strategy: type-guard

Type guard

static boolean isSupportedTopicCollection(TopicCollection c) {
    return c instanceof TopicIdCollection || c instanceof TopicNameCollection;
}

Try / catch

if (!(topics instanceof TopicIdCollection || topics instanceof TopicNameCollection)) {
    throw new IllegalArgumentException("Use TopicCollection.ofTopicNames(...) or TopicCollection.ofTopicIds(...)");
}
admin.deleteTopics(topics, options);

Prevention

When it happens

Trigger: Calling admin.deleteTopics(topicCollection, opts) where topicCollection is a custom subclass of TopicCollection, or null-extended in a way that fails both instanceof checks; or a test/mocked TopicCollection that doesn't extend TopicIdCollection/TopicNameCollection.

Common situations: Custom abstraction wrapping TopicCollection; passing null (would NPE earlier, but a no-op placeholder object triggers this); library/version mismatch where a subclass existed in an older fork; code that constructs TopicCollection via reflection incorrectly.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/ad246f2bae74e83a.json. Report an issue: GitHub.