apache/rocketmq · error · MQClientException

The broker service address not found

Error message

The broker service address not found

What it means

Thrown by recallMessage when no broker address can be resolved: findBrokerAddressInPublish for the broker named in the decoded handle returned empty, and the fallback findBrokerAddrByTopic(topic) also returned empty (with a preceding 'can't find broker service address' warn log). The client therefore has no endpoint to send the RecallMessageRequestHeader to. The code comments note the fallback exists to support multi-proxy endpoints.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java:1593

        if (NamespaceUtil.isRetryTopic(topic) || NamespaceUtil.isDLQTopic(topic)) {
            throw new MQClientException("topic is not supported", null);
        }
        RecallMessageHandle.HandleV1 handleEntity;
        try {
            handleEntity = (RecallMessageHandle.HandleV1) RecallMessageHandle.decodeHandle(recallHandle);
        } catch (Exception e) {
            throw new MQClientException(e.getMessage(), null);
        }

        tryToFindTopicPublishInfo(topic);
        String brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(handleEntity.getBrokerName());
        brokerAddr = StringUtils.isNotEmpty(brokerAddr) ?
            // find another address to support multi proxy endpoints,
            // may cause failure request in proxy-less mode when the broker is temporarily unavailable
            brokerAddr : this.mQClientFactory.findBrokerAddrByTopic(topic);
        if (StringUtils.isEmpty(brokerAddr)) {
            log.warn("can't find broker service address. {}", handleEntity.getBrokerName());
            throw new MQClientException("The broker service address not found", null);
        }
        RecallMessageRequestHeader requestHeader = new RecallMessageRequestHeader();
        requestHeader.setProducerGroup(this.defaultMQProducer.getProducerGroup());
        requestHeader.setTopic(topic);
        requestHeader.setRecallHandle(recallHandle);
        requestHeader.setBrokerName(handleEntity.getBrokerName());
        return this.mQClientFactory.getMQClientAPIImpl().recallMessage(brokerAddr,
            requestHeader, this.defaultMQProducer.getSendMsgTimeout());
    }

    public void setCallbackExecutor(final ExecutorService callbackExecutor) {
        this.mQClientFactory.getMQClientAPIImpl().getRemotingClient().setCallbackExecutor(callbackExecutor);
    }

    public ExecutorService getAsyncSenderExecutor() {
        return null == asyncSenderExecutor ? defaultAsyncSenderExecutor : asyncSenderExecutor;
    }

View on GitHub (pinned to 293f588571)

Solutions

  1. Wait for route refresh (~30s) or force it via producer.fetchPublishMessageQueues(topic), then retry the recall.
  2. Confirm the broker named in the handle (decode it or check the warn log's broker name) is registered and has a writable master: check mqadmin brokerStatus / broker list on the nameserver.
  3. If the broker was decommissioned, the handle is unusable — re-issue recall from an environment where that broker exists.
  4. In proxy mode, verify the proxy endpoints are configured so findBrokerAddrByTopic can supply an alternative address.

Example fix

// before
String msgId = producer.recallMessage(topic, handle); // may throw immediately after start

// after
producer.fetchPublishMessageQueues(topic); // force route refresh
try {
    String msgId = producer.recallMessage(topic, handle);
} catch (MQClientException e) {
    if (e.getMessage().contains("broker service address not found")) {
        scheduler.schedule(() -> retryRecall(topic, handle), Duration.ofSeconds(30)); // retry after route refresh
    } else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// force the client's route table to refresh before recalling
if (producer.fetchPublishMessageQueues(topic).isEmpty()) {
    throw new IllegalStateException("no route for " + topic + "; broker address unresolvable");
}

Try / catch

try {
    producer.recallMessage(topic, handle);
} catch (MQClientException e) {
    if (e.getMessage() != null && e.getMessage().contains("broker service address not found")) {
        producer.fetchPublishMessageQueues(topic);      // trigger route refresh
        scheduler.schedule(() -> recallQuietly(topic, handle), Duration.ofSeconds(30));
    } else throw e;
}

Prevention

When it happens

Trigger: Calling recallMessage when the broker named in the handle is not currently registered in the client's route table (broker down/restarted, route refresh pending), or when the topic's route has no master broker available for publishing.

Common situations: Broker outage at recall time; recalling long after the original send so the handle's brokerName no longer exists (renamed/decommissioned broker); client route cache stale right after startup; proxy deployments where the topic route lacks the specific broker from the handle.

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/0c3ed3a3f2f5bbc6. Report an issue: GitHub.