{"record":{"id":"148d7d68ff8536a1","repo":"apache/pulsar","slug":"invalid-version-string-in-lookup-data-for-broker","errorCode":null,"errorMessage":"Invalid version string in lookup data for broker \"${brokerId}\": \"${version}\")","messagePattern":"Invalid 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":134,"sourceCode":"        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;\n            }\n        }\n\n        return latestVersion;\n    }\n\n    @Override\n    public String name() {\n        return FILTER_NAME;\n    }\n}","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/extensions/filter/BrokerVersionFilter.java#L116-L152","documentation":"getLatestVersionNumber parses each broker's version string with Version.valueOf (SemVer). If a broker reports a string that is not valid SemVer (e.g. '3.2.0-SNAPSHOT-with-suffix', 'unknown', 'custom-build'), parsing fails and a BrokerFilterBadVersionException is thrown quoting the bad version, disabling PreferLaterVersions.","triggerScenarios":"Any broker in the candidate map publishes a brokerVersion() string that Version.valueOf cannot parse (null handled separately at error 261; this is the non-empty-but-unparseable case).","commonSituations":"Custom/forked broker builds with non-semver version strings, snapshot builds, a build that overrode the project version, or hand-edited lookup data in tests.","solutions":["Rebuild/deploy the offending broker with a valid SemVer version string (MAJOR.MINOR.PATCH).","Identify the broker named in the message and check its reported version via its /admin/v2/broker-status or lookup data.","Disable preferLaterVersions or remove broker_version_filter until all brokers report valid versions.","In tests, always set a parseable version like \"3.2.1\" on BrokerLookupData."],"exampleFix":"// before\nString version = \"3.2.0-custom-build\"; // not parseable\n// after\nString version = \"3.2.0\"; // valid SemVer; put build info elsewhere","handlingStrategy":"validation","validationCode":"try {\n    Version.valueOf(broker.getBrokerVersion());\n} catch (Exception e) {\n    throw new IllegalStateException(\"Non-semver version on \" + brokerId + \": \" + broker.getBrokerVersion());\n}","typeGuard":"boolean isSemver(String v) {\n    if (v == null) return false;\n    try { Version.valueOf(v); return true; } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    latest = filter.getLatestVersionNumber(brokerMap);\n} catch (BrokerFilterBadVersionException e) {\n    log.warn(\"Bad version in lookup data, filter disabled: {}\", e.getMessage());\n}","preventionTips":["Standardize on SemVer MAJOR.MINOR.PATCH broker versions; keep build metadata as separate SemVer build labels if needed.","Validate reported broker version at broker startup with Version.valueOf.","After custom builds, verify the version via the broker's health/admin endpoint before joining the cluster."],"tags":["load-manager","broker-filter","semver","invalid-version-format"],"backgroundTag":"invalid-semver-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"}