apache/kafka · warning · StaleMetadataException

Metadata fetch failed due to missing broker list

Error message

Metadata fetch failed due to missing broker list

What it means

A StaleMetadataException thrown while handling a MetadataResponse during listGroups: the response carried an empty broker list. The client treats this as stale metadata so the Call machinery can retry against fresh metadata. It is a retryable signal, not a hard failure.

Source

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

    @Override
    public ListGroupsResult listGroups(ListGroupsOptions options) {
        final KafkaFutureImpl<Collection<Object>> all = new KafkaFutureImpl<>();
        final long nowMetadata = time.milliseconds();
        final long deadline = calcDeadlineMs(nowMetadata, options.timeoutMs());
        runnable.call(new Call("findAllBrokers", deadline, new LeastLoadedNodeProvider()) {
            @Override
            MetadataRequest.Builder createRequest(int timeoutMs) {
                return new MetadataRequest.Builder(new MetadataRequestData()
                    .setTopics(Collections.emptyList())
                    .setAllowAutoTopicCreation(true));
            }

            @Override
            void handleResponse(AbstractResponse abstractResponse) {
                MetadataResponse metadataResponse = (MetadataResponse) abstractResponse;
                Collection<Node> nodes = metadataResponse.brokers();
                if (nodes.isEmpty())
                    throw new StaleMetadataException("Metadata fetch failed due to missing broker list");

                HashSet<Node> allNodes = new HashSet<>(nodes);
                final ListGroupsResults results = new ListGroupsResults(allNodes, all);

                for (final Node node : allNodes) {
                    final long nowList = time.milliseconds();
                    runnable.call(new Call("listGroups", deadline, new ConstantNodeIdProvider(node.id())) {
                        @Override
                        ListGroupsRequest.Builder createRequest(int timeoutMs) {
                            List<String> groupTypes = options.types()
                                .stream()
                                .map(GroupType::toString)
                                .collect(Collectors.toList());
                            List<String> groupStates = options.groupStates()
                                .stream()
                                .map(GroupState::toString)
                                .collect(Collectors.toList());
                            return new ListGroupsRequest.Builder(new ListGroupsRequestData()

View on GitHub (pinned to 996fb4585a)

Solutions

  1. Let the Admin client retry: StaleMetadataException is designed to trigger Call retries, so ensure retries are not disabled and the overall timeout allows a few attempts.
  2. If it persists, verify the cluster is healthy (brokers up, advertised.listeners correct, controller elected).
  3. Retry the listGroups operation after a short delay once metadata has refreshed.

Example fix

// before (single attempt, no retry budget)
ListGroupsOptions opts = new ListGroupsOptions().timeoutMs(2000);
admin.listGroups(opts).all().get();

// after (allow retries + longer deadline)
ListGroupsOptions opts = new ListGroupsOptions().timeoutMs(30000);
admin.listGroups(opts).all().get();
Defensive patterns

Strategy: retry

Validate before calling

// ensure retry budget and deadline allow recovery
ListGroupsOptions opts = new ListGroupsOptions().timeoutMs(60_000);
// retries are handled by the Call framework; do not disable them

Try / catch

// StaleMetadataException is retryable; let KafkaFuture retries handle it,
// then retry the top-level operation if it still fails.
try {
    admin.listGroups(opts).all().get();
} catch (ExecutionException e) {
    if (e.getCause() instanceof StaleMetadataException) {
        // wait for metadata refresh, then retry admin.listGroups
    }
}

Prevention

When it happens

Trigger: listGroups (or listConsumerGroups/listConsumerGroupOffsets that fans out to nodes) issues an empty-topic MetadataRequest, and the response.brokers() collection is empty. Typical of a cluster that is starting up, mid-rebalance, or temporarily unreachable.

Common situations: Calling listGroups immediately after bringing a cluster up before brokers register; network partition where the contacted node has no peer info; a misconfigured broker with no advertised.listeners; during controlled shutdown windows.

Related errors


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