apache/kafka · error · IllegalArgumentException

The TopicCollection: provided did not match any supported…

Error message

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

What it means

An IllegalArgumentException thrown by KafkaAdminClient.deleteTopics(TopicCollection, ...) when the TopicCollection subclass is neither TopicIdCollection nor TopicNameCollection. Only those two concrete subclasses are supported; anything else (including a custom or null subclass) is a programming error.

Solutions

  1. Use TopicCollection.ofTopicNames(...) or TopicCollection.ofTopicIds(...) to build the collection.
  2. Ensure the value passed is non-null and is one of the two supported concrete types.
  3. If you have a custom wrapper, unwrap it to a supported TopicCollection before calling deleteTopics.

Example fix

// before
admin.deleteTopics(myCustomTopicCollection, opts);

// after
admin.deleteTopics(TopicCollection.ofTopicNames(Arrays.asList("t1","t2")), opts);
Defensive patterns

Strategy: validation

Validate before calling

TopicCollection topics = (names != null && !names.isEmpty())
    ? TopicCollection.ofTopicNames(names)
    : TopicCollection.ofTopicIds(ids);
admin.deleteTopics(topics, options);

Type guard

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

Prevention

When it happens

Trigger: Passing a custom TopicCollection subclass, or passing null cast to TopicCollection, to admin.deleteTopics(...). Subclassing TopicCollection in user code and expecting it to be honored.

Common situations: Library code that wraps TopicCollection with its own type; null returned from a helper that was expected to produce a collection; migrating between API versions where a third collection type was removed.

Related errors


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

Appendix: source

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

                // 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 996fb4585a)