apache/pulsar · warning · BrokerFilterBadVersionException

Unable to determine latest version since broker version map

Error message

Unable to determine latest version since broker version map was empty

What it means

BrokerVersionFilter.getLatestVersionNumber scans the map of candidate brokers to find the newest broker version (semver via java-semver, build-aware ordering). If the map is empty there is no version to compare, so it throws BrokerFilterBadVersionException. In filterAsync this failure causes the PreferLaterVersions filtering step to fail, forcing the load manager to fall back to the full unfiltered broker set.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/extensions/filter/BrokerVersionFilter.java:111

        return CompletableFuture.completedFuture(brokers);
    }

    /**
     * Get the most recent broker version number from the broker lookup data of all the running brokers.
     * The version number is from the build artifact in the pom and got added to the package when it was built by Maven
     *
     * @param brokerMap
     *             The BrokerId -> BrokerLookupData Map.
     * @return The most recent broker version
     * @throws BrokerFilterBadVersionException
     *            If the most recent version is undefined (e.g., a bad broker version was encountered or a broker
     *            does not have a version string in its lookup data.
     */
    public Version getLatestVersionNumber(Map<String, BrokerLookupData> brokerMap)
            throws BrokerFilterBadVersionException {

        if (brokerMap.size() == 0) {
            throw new BrokerFilterBadVersionException(
                    "Unable to determine latest version since broker version map was empty");
        }

        Version latestVersion = null;
        for (Map.Entry<String, BrokerLookupData> entry : brokerMap.entrySet()) {
            String brokerId = entry.getKey();
            String version = entry.getValue().brokerVersion();
            if (null == version || version.length() == 0) {
                log.warn().attr("broker", brokerId)
                        .log("No version string in lookup data for broker; disabling PreferLaterVersions feature");
                // Trigger the load manager to reset all the brokers to the original set
                throw new BrokerFilterBadVersionException("No version string in lookup data for broker \""
                        + brokerId + "\"");
            }
            Version brokerVersionVersion;
            try {
                brokerVersionVersion = Version.valueOf(version);
            } catch (Exception x) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Check that other broker filters are not removing all candidates before broker_version_filter runs (review loadBalancerBrokerFilterNames order).
  2. Verify brokers are actually reporting load data to the metadata store and that the ExtensibleLoadManager has a non-empty available-broker map.
  3. Set preferLaterVersions=false or remove broker_version_filter from loadBalancerBrokerFilterNames if version-based filtering is not needed.
  4. If calling getLatestVersionNumber programmatically, guard brokerMap.isEmpty() before invoking.

Example fix

// before
Version latest = filter.getLatestVersionNumber(brokers);
// after
if (brokers.isEmpty()) {
    return CompletableFuture.completedFuture(brokers); // let load manager handle empty set
}
Version latest = filter.getLatestVersionNumber(brokers);
Defensive patterns

Strategy: validation

Validate before calling

if (brokers == null || brokers.isEmpty()) {
    return CompletableFuture.completedFuture(brokers); // skip version filter
}
return filter.filterAsync(brokers, serviceUnit, context);

Try / catch

try {
    Version latest = filter.getLatestVersionNumber(brokerMap);
} catch (BrokerFilterBadVersionException e) {
    log.warn("Version filter disabled: {}", e.getMessage());
    // fall back to unfiltered broker set
}

Prevention

When it happens

Trigger: filterAsync is invoked with an empty candidate broker map while loadBalancerBrokerFilterNames includes broker_version_filter and preferLaterVersions=true; getLatestVersionNumber is also called directly with an empty map.

Common situations: All brokers have been filtered out by earlier BrokerFilters in the chain, no brokers are registered in the load-data store (fresh cluster, metadata connectivity problems), or a custom filter upstream removed every candidate.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/327cf72411fffbc2. Report an issue: GitHub.