apache/rocketmq · error · MQClientException
Broker[{destBrokerName}] master node does not exist
Error message
Broker[{destBrokerName}] master node does not exist What it means
Thrown by sendMessageBack when no master broker address can be resolved for the target broker. The method maps the (possibly logical-queue-mocked) broker name through findBrokerAddressInPublish or falls back to the message's storeHost; if both yield a blank address, the retry-message cannot be routed and the exception is raised.
Source
Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPullConsumerImpl.java:658
public void updateConsumeOffsetToBroker(MessageQueue mq, long offset, boolean isOneway) throws RemotingException,
MQBrokerException, InterruptedException, MQClientException {
this.offsetStore.updateConsumeOffsetToBroker(mq, offset, isOneway);
}
@Deprecated
public void sendMessageBack(MessageExt msg, int delayLevel, final String brokerName, String consumerGroup)
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
try {
String destBrokerName = brokerName;
if (destBrokerName != null && destBrokerName.startsWith(MixAll.LOGICAL_QUEUE_MOCK_BROKER_PREFIX)) {
destBrokerName = this.mQClientFactory.getBrokerNameFromMessageQueue(this.defaultMQPullConsumer.queueWithNamespace(new MessageQueue(msg.getTopic(), msg.getBrokerName(), msg.getQueueId())));
}
String brokerAddr = (null != destBrokerName) ? this.mQClientFactory.findBrokerAddressInPublish(destBrokerName)
: RemotingHelper.parseSocketAddressAddr(msg.getStoreHost());
if (UtilAll.isBlank(brokerAddr)) {
throw new MQClientException("Broker[" + destBrokerName + "] master node does not exist", null);
}
if (UtilAll.isBlank(consumerGroup)) {
consumerGroup = this.defaultMQPullConsumer.getConsumerGroup();
}
this.mQClientFactory.getMQClientAPIImpl().consumerSendMessageBack(brokerAddr, brokerName, msg, consumerGroup,
delayLevel, 3000, this.defaultMQPullConsumer.getMaxReconsumeTimes());
} catch (Exception e) {
log.error("sendMessageBack Exception, " + this.defaultMQPullConsumer.getConsumerGroup(), e);
Message newMsg = new Message(MixAll.getRetryTopic(this.defaultMQPullConsumer.getConsumerGroup()), msg.getBody());
String originMsgId = MessageAccessor.getOriginMessageId(msg);
MessageAccessor.setOriginMessageId(newMsg, UtilAll.isBlank(originMsgId) ? msg.getMsgId() : originMsgId);
newMsg.setFlag(msg.getFlag());
MessageAccessor.setProperties(newMsg, msg.getProperties());
MessageAccessor.putProperty(newMsg, MessageConst.PROPERTY_RETRY_TOPIC, msg.getTopic());
MessageAccessor.setReconsumeTime(newMsg, String.valueOf(msg.getReconsumeTimes() + 1));View on GitHub (pinned to 293f588571)
Solutions
- Retry after refreshing routes: consumer.getDefaultMQPullConsumerImpl() internals aside, call updateTopicRouteInfoFromNameServer indirectly by retrying the operation after a short delay
- Check nameserver connectivity (namesrvAddr) so the route table keeps a current master for the broker
- Verify the target broker is RUNNING (not in maintenance) via broker admin status or dashboard
- As the code itself does, fall back to building a retry message to the retry topic (the catch block already does this) — ensure that fallback path is reachable and its broker is up
Example fix
// before
consumer.getDefaultMQPullConsumerImpl().sendMessageBack(msg, 3, "broker-a", group); // fails if route stale
// after
// refresh route then retry
for (int i = 0; i < 3; i++) {
try {
impl.sendMessageBack(msg, 3, "broker-a", group);
break;
} catch (MQClientException e) {
Thread.sleep(1000L << i); // wait for route refresh
}
} Defensive patterns
Strategy: retry
Validate before calling
String addr = consumer.fetchMessageQueues(topic) != null ? "route-ok" : null; // indirect route check
if (addr == null) { /* refresh/wait before sendMessageBack */ } Try / catch
catch (MQClientException e) { if (e.getMessage().contains("master node does not exist")) { sleepBackoff(); retryWithLimit(); } else throw e; } Prevention
- Keep nameserver address valid so route caches refresh
- Wrap sendMessageBack in bounded retry with backoff
- Monitor broker availability before issuing retry messages
When it happens
Trigger: Calling sendMessageBack(msg, delayLevel, brokerName, consumerGroup) where brokerName has no live master in the client's route table (getTopicRouteInfo failed or is stale); the broker named in the message is down or in maintenance so only slaves are known; using logical queues (MixAll.LOGICAL_QUEUE_MOCK_BROKER_PREFIX) whose mapping cannot be resolved.
Common situations: Broker failover in progress while the client's route cache still points at the dead master; nameserver unreachable at retry time so findBrokerAddressInPublish returns null; heterogeneous deployment where the storeHost in the message is not reachable from the client network.
Related errors
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/c680ef6e59617f7b.
Report an issue: GitHub.