apache/kafka · critical · IllegalStateException

There are no nodes in the Kafka cluster

Error message

There are no nodes in the Kafka cluster

What it means

Thrown as IllegalStateException by NetworkClient.handleEmptyNodeList() when leastLoadedNode is asked for a broker but metadataUpdater.fetchNodes() is empty AND bootstrap is either disabled or already considered complete. It indicates the client has no broker to talk to and no remaining bootstrap path to discover one. This is a terminal metadata state, not a transient outage.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/NetworkClient.java:910

        } else if (foundCanConnect != null) {
            log.trace("Found least loaded node {} with no active connection", foundCanConnect);
            return new LeastLoadedNode(foundCanConnect, atLeastOneConnectionReady);
        } else {
            log.trace("Least loaded node selection failed to find an available node");
            return new LeastLoadedNode(null, atLeastOneConnectionReady);
        }
    }

    /**
     * Handle the case when there are no nodes available.
     * <p>
     * If bootstrap is disabled or already complete, throw IllegalStateException.
     * If bootstrap is enabled but not yet complete, return an empty {@link LeastLoadedNode}
     * so that the caller can continue polling while DNS resolution finishes.
     */
    private LeastLoadedNode handleEmptyNodeList() {
        if (bootstrapConfiguration == BootstrapConfiguration.DISABLED || metadataUpdater.isBootstrapped()) {
            throw new IllegalStateException("There are no nodes in the Kafka cluster");
        }

        log.debug("No nodes available yet, still in bootstrap phase");
        return new LeastLoadedNode(null, false);
    }

    public static AbstractResponse parseResponse(ByteBuffer responseBuffer, RequestHeader requestHeader) {
        try {
            return AbstractResponse.parseResponse(responseBuffer, requestHeader);
        } catch (BufferUnderflowException e) {
            throw new SchemaException("Buffer underflow while parsing response for request with header " + requestHeader, e);
        } catch (CorrelationIdMismatchException e) {
            if (SaslClientAuthenticator.isReserved(requestHeader.correlationId())
                && !SaslClientAuthenticator.isReserved(e.responseCorrelationId()))
                throw new SchemaException("The response is unrelated to Sasl request since its correlation id is "
                    + e.responseCorrelationId() + " and the reserved range for Sasl request is [ "
                    + SaslClientAuthenticator.MIN_RESERVED_CORRELATION_ID + ","
                    + SaslClientAuthenticator.MAX_RESERVED_CORRELATION_ID + "]");

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Verify bootstrap.servers is non-empty and points to reachable brokers (host:port, comma-separated).
  2. Confirm at least one broker is actually up and advertising itself: kafka-broker-api-versions --bootstrap-server HOST:PORT.
  3. Check the KRaft controller quorum / broker registration so the metadata snapshot contains nodes.
  4. Add more than one bootstrap host so a single dead host does not empty the node list.
  5. If using a custom BootstrapConfiguration, ensure it is not set to DISABLED without seeding nodes.

Example fix

// before
props.put("bootstrap.servers", "");
// after
props.put("bootstrap.servers", "broker1:9092,broker2:9092,broker3:9092");
Defensive patterns

Strategy: validation

Validate before calling

// Verify the cluster has known nodes before relying on leastLoadedNode / metadata.
java.util.List<org.apache.kafka.common.Node> nodes = metadata.fetch().nodes();
if (nodes.isEmpty()) {
    throw new IllegalStateException(
        "No Kafka brokers known. Check bootstrap.servers=" + bootstrapServers
        + " and that the cluster is reachable.");
}
// Proceed only after metadata has at least one broker.

Type guard

// Predicate that captures the real precondition: metadata populated AND bootstrap done.
public static boolean clusterIsKnown(org.apache.kafka.clients.Metadata metadata) {
    return metadata != null && metadata.fetch() != null
            && !metadata.fetch().nodes().isEmpty();
}
// Also assert bootstrap.servers is non-empty before constructing the client:
if (bootstrapServers == null || bootstrapServers.isBlank()) {
    throw new IllegalArgumentException("bootstrap.servers must be set");
}

Try / catch

try {
    Node n = networkClient.leastLoadedNode(now).node();
} catch (IllegalStateException e) {
    if ("There are no nodes in the Kafka cluster".equals(e.getMessage())) {
    // Bootstrap incomplete or no brokers discovered. Do NOT retry in a tight loop;
    // verify connectivity to bootstrap.servers, re-check DNS, then rebuild the client.
    }
    throw e;
}

Prevention

When it happens

Trigger: bootstrap.servers resolves and bootstrap completes, then every node is later removed from the metadata cache (or the cluster advertised zero nodes), leaving fetchNodes() empty. Also when bootstrap is explicitly disabled (BootstrapConfiguration.DISABLED) and no nodes have ever been seeded. The exception surfaces from leastLoadedNode, which Admin/Producer/Consumer call to pick a request target.

Common situations: Empty or whitespace-only bootstrap.servers; a bootstrap.servers that points only to a dead host with no fallback; misconfigured controller/broker in KRaft that returns an empty node list; a load balancer in front of brokers returning empty membership; clients built without bootstrap.servers when bootstrap is disabled.

Related errors


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