{"record":{"id":"88389efcedf1d734","repo":"apache/rocketmq","slug":"find-filter-server-failed-broker-addr-brokeradd","errorCode":null,"errorMessage":"Find Filter Server Failed, Broker Addr: {brokerAddr} topic: {topic}","messagePattern":"Find Filter Server Failed, Broker Addr: (.+?) topic: (.+?)","errorType":"exception","errorClass":"MQClientException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/org/apache/rocketmq/client/impl/consumer/PullAPIWrapper.java","lineNumber":311,"sourceCode":"\n        return MixAll.MASTER_ID;\n    }\n\n    private String computePullFromWhichFilterServer(final String topic, final String brokerAddr)\n        throws MQClientException {\n        ConcurrentMap<String, TopicRouteData> topicRouteTable = this.mQClientFactory.getTopicRouteTable();\n        if (topicRouteTable != null) {\n            TopicRouteData topicRouteData = topicRouteTable.get(topic);\n            if (topicRouteData != null && topicRouteData.getFilterServerTable() != null) {\n                List<String> list = topicRouteData.getFilterServerTable().get(brokerAddr);\n\n                if (list != null && !list.isEmpty()) {\n                    return list.get(randomNum() % list.size());\n                }\n            }\n        }\n\n        throw new MQClientException(\"Find Filter Server Failed, Broker Addr: \" + brokerAddr + \" topic: \"\n            + topic, null);\n    }\n\n    public boolean isConnectBrokerByUser() {\n        return connectBrokerByUser;\n    }\n\n    public void setConnectBrokerByUser(boolean connectBrokerByUser) {\n        this.connectBrokerByUser = connectBrokerByUser;\n\n    }\n\n    public int randomNum() {\n        int value = random.nextInt();\n        if (value < 0) {\n            value = Math.abs(value);\n            if (value < 0)\n                value = 0;","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/client/src/main/java/org/apache/rocketmq/client/impl/consumer/PullAPIWrapper.java#L293-L329","documentation":"Thrown by PullAPIWrapper.findFilterServerAddr when the client's cached topic route data contains no filter-server list for the given broker address. Class-filter (server-side Java filter) consumption requires a separately deployed Filtersrv; its addresses are carried in TopicRouteData.filterServerTable. If that table has no entry for the broker, the client cannot upload the filter class, so class filtering fails.","triggerScenarios":"A consumer in class-filter mode (subscribe(topic, className, source)) attempts to register the filter and findFilterServerAddr finds filterServerTable null, missing the brokerAddr key, or an empty list — for example when the deployment runs no Filtersrv instances or the broker failed to register its filter servers with the NameServer.","commonSituations":"Enabling class filtering without deploying the Filtersrv component (default installs omit it); Filtersrv crashed or not configured on the broker (filterServerNum in broker config); route cache on the client predates filter server registration; using class filters against broker versions/distros that dropped Filtersrv support in favor of SQL92.","solutions":["Deploy or restart the Filtersrv and confirm the broker registers it (broker config filterNum/filterServerNum, check broker log 'filter server' registration), then refresh client routes","Prefer SQL92 filtering (MessageSelector.bySql) which runs in-broker since 4.1.0 and needs no Filtersrv","If staying with class filters, verify TopicRouteData.filterServerTable via mqadmin topicRoute and ensure the key matches the broker address the client is using"],"exampleFix":"// before\nconsumer.subscribe(topic, \"com.acme.MyFilter\", src); // no Filtersrv deployed -> find fails\n// after: switch to in-broker SQL92, no Filtersrv needed\nconsumer.subscribe(topic, MessageSelector.bySql(\"orderAmount > 1000\"));","handlingStrategy":"validation","validationCode":"DefaultMQAdminExt admin = new DefaultMQAdminExt(); admin.start();\nTopicRouteData route = admin.examineTopicRouteInfo(topic);\nboolean hasFs = route.getFilterServerTable() != null && !route.getFilterServerTable().isEmpty();\nif (!hasFs) throw new IllegalStateException(\"no Filtersrv registered; class filters unavailable\");","typeGuard":null,"tryCatchPattern":"try { consumer.subscribe(topic, cls, src); } catch (MQClientException e) { if (String.valueOf(e.getCause()).contains(\"Filter Server\") || /* pull-time */ true) { log.error(\"Filtersrv missing, falling back to SQL92\"); consumer.subscribe(topic, MessageSelector.bySql(sqlExpr)); } }","preventionTips":["Deploy and monitor Filtersrv before enabling class filters","Prefer SQL92: no extra process, supported in-broker since 4.1.0","Alert on empty filterServerTable in route data when class filters are in use"],"tags":["rocketmq","filter-server","class-filter","deployment","route-discovery"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}