apache/pulsar · error · IllegalStateException
No available broker found.
Error message
No available broker found.
What it means
During load-manager migration, RedirectManagerForLoadManagerMigration.redirectIfLoadBalancerOnBrokerIsNotExpected fetches the available-broker lookup data; if the map is empty there is no broker to redirect to or to evaluate, so the returned future fails with IllegalStateException 'No available broker found.'
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/extensions/manager/RedirectManagerForLoadManagerMigration.java:104
* Redirect the request to another broker if the load balancer on the current broker is using the load manager
* of the latest service lookup data available in the metadata store.
*
* @param options lookup options
* @return lookup result
*/
public CompletableFuture<Optional<LookupResult>> redirectIfLoadBalancerOnBrokerIsNotExpected(
LookupOptions options) {
if (!pulsar.getConfiguration().isLoadManagerMigrationEnabled()) {
// no-op when load manager migration is disabled.
return CompletableFuture.completedFuture(Optional.empty());
}
String currentLMClassName = pulsar.getConfiguration().getLoadManagerClassName();
boolean debug = ExtensibleLoadManagerImpl.debug(pulsar.getConfiguration(), log);
return getAvailableBrokerLookupDataAsync().thenApply(lookupDataMap -> {
if (lookupDataMap.isEmpty()) {
String errorMsg = "No available broker found.";
log.warn(errorMsg);
throw new IllegalStateException(errorMsg);
}
AtomicReference<BrokerLookupData> latestServiceLookupData = new AtomicReference<>();
AtomicLong lastStartTimestamp = new AtomicLong(0L);
lookupDataMap.forEach((key, value) -> {
if (lastStartTimestamp.get() <= value.getStartTimestamp()) {
lastStartTimestamp.set(value.getStartTimestamp());
latestServiceLookupData.set(value);
}
});
if (latestServiceLookupData.get() == null) {
String errorMsg = "No latest service lookup data found.";
log.warn(errorMsg);
throw new IllegalStateException(errorMsg);
}
if (Objects.equals(latestServiceLookupData.get().getLoadManagerClassName(), currentLMClassName)) {
if (debug) {
log.info().attr("name", currentLMClassName)View on GitHub (pinned to 820761864e)
Solutions
- Wait for brokers to start and publish load data, then retry the lookup.
- Check broker logs and the metadata store (e.g. /loadbalance/brokers in ZooKeeper et al.) for registered brokers; fix connectivity if empty.
- Ensure at least one broker is running and registered with the ExtensibleLoadManager before sending lookups.
- Catch the IllegalStateException in the lookup path and return a 503 'Service unavailable' style response to clients.
Example fix
// before
return redirectIfLoadBalancerOnBrokerIsNotExpected(...);
// after
return redirectIfLoadBalancerOnBrokerIsNotExpected(...)
.exceptionally(ex -> {
if (ex.getCause() instanceof IllegalStateException) {
throw new RestException(Response.Status.SERVICE_UNAVAILABLE, "No available brokers");
}
throw FutureUtil.wrapToCompletionException(ex);
}); Defensive patterns
Strategy: try-catch
Validate before calling
boolean hasBrokers = brokerRegistry.snapshot().values().stream()
.anyMatch(d -> !d.isBrokerShuttingDown());
if (!hasBrokers) { /* defer/redirect with 503 */ } Try / catch
redirectIfLoadBalancerOnBrokerIsNotExpected(...)
.exceptionally(ex -> {
Throwable c = FutureUtil.unwrapCompletionException(ex);
if (c instanceof IllegalStateException && c.getMessage().contains("No available broker")) {
throw new RestException(Response.Status.SERVICE_UNAVAILABLE, c.getMessage());
}
throw FutureUtil.wrapToCompletionException(c);
}); Prevention
- Gate client traffic behind health checks that confirm at least one registered broker.
- Alert when the load-manager broker registry count drops to zero.
- Retry lookups with backoff during cluster startup.
When it happens
Trigger: A lookup reaches redirectIfLoadBalancerOnBrokerIsNotExpected while getAvailableBrokerLookupDataAsync returns an empty map (no brokers registered in the extensible load manager's broker registry).
Common situations: Cluster just started and no broker has published load data yet, metadata store connectivity issues wiped/emptied the registry, or all brokers were excluded/deregistered (shutdown, crash).
Related errors
- No latest service lookup data found.
- ${loadManagerClass} does not support this operation
- Unable to determine latest version since broker version map
- No version string in lookup data for broker "${brokerId}"
- Invalid version string in lookup data for broker "${brokerId
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/4e7a8c80db4c002b.
Report an issue: GitHub.