{"record":{"id":"0f875020264956a5","repo":"apache/pulsar","slug":"no-version-string-in-lookup-data-for-broker-bro","errorCode":null,"errorMessage":"No version string in lookup data for broker \"${brokerId}\"","messagePattern":"No version string in lookup data for broker \"(.+?)\"","errorType":"exception","errorClass":"BrokerFilterBadVersionException","httpStatus":null,"severity":"warning","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/extensions/filter/BrokerVersionFilter.java","lineNumber":123,"sourceCode":"     *            does not have a version string in its lookup data.\n     */\n    public Version getLatestVersionNumber(Map<String, BrokerLookupData> brokerMap)\n            throws BrokerFilterBadVersionException {\n\n        if (brokerMap.size() == 0) {\n            throw new BrokerFilterBadVersionException(\n                    \"Unable to determine latest version since broker version map was empty\");\n        }\n\n        Version latestVersion = null;\n        for (Map.Entry<String, BrokerLookupData> entry : brokerMap.entrySet()) {\n            String brokerId = entry.getKey();\n            String version = entry.getValue().brokerVersion();\n            if (null == version || version.length() == 0) {\n                log.warn().attr(\"broker\", brokerId)\n                        .log(\"No version string in lookup data for broker; disabling PreferLaterVersions feature\");\n                // Trigger the load manager to reset all the brokers to the original set\n                throw new BrokerFilterBadVersionException(\"No version string in lookup data for broker \\\"\"\n                        + brokerId + \"\\\"\");\n            }\n            Version brokerVersionVersion;\n            try {\n                brokerVersionVersion = Version.valueOf(version);\n            } catch (Exception x) {\n                log.warn().attr(\"broker\", brokerId).attr(\"version\", version)\n                        .log(\"Invalid version string in lookup data for broker;\"\n                                + \" disabling PreferLaterVersions feature\");\n                // Trigger the load manager to reset all the brokers to the original set\n                throw new BrokerFilterBadVersionException(\"Invalid version string in lookup data for broker \\\"\"\n                        + brokerId + \"\\\": \\\"\" + version + \"\\\")\");\n            }\n\n            if (latestVersion == null) {\n                latestVersion = brokerVersionVersion;\n            } else if (Version.BUILD_AWARE_ORDER.compare(latestVersion, brokerVersionVersion) < 0) {\n                latestVersion = brokerVersionVersion;","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/extensions/filter/BrokerVersionFilter.java#L105-L141","documentation":"When building the latest-version comparison, every broker's BrokerLookupData must carry a version string. If a broker's lookup data has a null or empty brokerVersion(), getLatestVersionNumber throws BrokerFilterBadVersionException naming that broker, disabling the PreferLaterVersions feature for the lookup.","triggerScenarios":"A broker registered in the load manager's broker map reports BrokerLookupData with a null/empty brokerVersion() while preferLaterVersions=true and broker_version_filter is active.","commonSituations":"A broker in a rolling upgrade is running an old/custom build that does not publish its version into lookup data; a broker registration was corrupted or partially written; a test stub BrokerLookupData was built without a version.","solutions":["Fix the offending broker so it reports a real version (use a standard Pulsar distribution; ensure the version is set in the broker's lookup/load data).","Restart or re-register the offending broker so its load data is rewritten.","Disable the feature: preferLaterVersions=false or remove broker_version_filter from loadBalancerBrokerFilterNames.","In tests, populate BrokerLookupData.brokerVersion with a valid semver string."],"exampleFix":"// before (test stub)\nBrokerLookupData data = new BrokerLookupData(url, tlsUrl, httpUrl, httpTlsUrl, ...); // version missing\n// after\nBrokerLookupData data = new BrokerLookupData(url, tlsUrl, httpUrl, httpTlsUrl, ..., \"3.2.0\", ...);","handlingStrategy":"validation","validationCode":"String badBroker = brokerMap.entrySet().stream()\n    .filter(e -> e.getValue() == null || e.getValue().brokerVersion() == null\n        || e.getValue().brokerVersion().isEmpty())\n    .map(Map.Entry::getKey)\n    .findFirst().orElse(null);\nif (badBroker != null) throw new IllegalStateException(\"Broker without version: \" + badBroker);","typeGuard":"boolean hasVersion(BrokerLookupData d) {\n    return d != null && d.brokerVersion() != null && !d.brokerVersion().isEmpty();\n}","tryCatchPattern":"try {\n    latest = filter.getLatestVersionNumber(brokerMap);\n} catch (BrokerFilterBadVersionException e) {\n    log.warn(\"PreferLaterVersions disabled: {}\", e.getMessage());\n}","preventionTips":["Ensure all brokers run standard builds that publish a version in lookup data.","During rolling upgrades, upgrade brokers without version metadata first.","In tests, always populate brokerVersion on stub BrokerLookupData."],"tags":["load-manager","broker-filter","version-comparison","missing-metadata"],"backgroundTag":"missing-version-string","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}