apache/rocketmq · error · MQClientException

select message queue return null.

Error message

select message queue return null.

What it means

MQClientException thrown from invokeMessageQueueSelector when the MessageQueueSelector.select(...) completes without throwing but returns null (the client also null-checks the namespace-wrapped result). A null selection cannot be mapped to a broker queue, so the send-select call aborts before any network I/O. Distinct from error 267: here the selector ran cleanly but produced no queue.

Source

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

                List<MessageQueue> messageQueueList =
                        mQClientFactory.getMQAdminImpl().parsePublishMessageQueues(topicPublishInfo.getMessageQueueList());
                Message userMessage = MessageAccessor.cloneMessage(msg);
                String userTopic = NamespaceUtil.withoutNamespace(userMessage.getTopic(), mQClientFactory.getClientConfig().getNamespace());
                userMessage.setTopic(userTopic);

                mq = mQClientFactory.getClientConfig().queueWithNamespace(selector.select(messageQueueList, userMessage, arg));
            } catch (Throwable e) {
                throw new MQClientException("select message queue threw exception.", e);
            }

            long costTime = System.currentTimeMillis() - beginStartTime;
            if (timeout < costTime) {
                throw new RemotingTooMuchRequestException("sendSelectImpl call timeout");
            }
            if (mq != null) {
                return mq;
            } else {
                throw new MQClientException("select message queue return null.", null);
            }
        }

        validateNameServerSetting();
        throw new MQClientException("No route info for this topic, " + msg.getTopic(), null);
    }

    public MessageQueue selectOneMessageQueue(final TopicPublishInfo tpInfo, final String lastBrokerName, final boolean resetIndex) {
        return this.mqFaultStrategy.selectOneMessageQueue(tpInfo, lastBrokerName, resetIndex);
    }

    public void updateFaultItem(final String brokerName, final long currentLatency, boolean isolation,
                                boolean reachable) {
        this.mqFaultStrategy.updateFaultItem(brokerName, currentLatency, isolation, reachable);
    }

    private void validateNameServerSetting() throws MQClientException {
        List<String> nsList = this.getMqClientFactory().getMQClientAPIImpl().getNameServerAddressList();

View on GitHub (pinned to 293f588571)

Solutions

  1. Make the selector always return a concrete queue; fall back to a default strategy (round-robin index or mqs.get(0)) instead of null
  2. If the lookup can legitimately miss, seed/initialize the mapping before returning or fall back to a hash of the message key
  3. Handle the empty-mqs case explicitly (throw a descriptive exception or pick queue 0) rather than letting the lambda fall through to null
  4. Add a unit test asserting select() never returns null for all expected inputs

Example fix

// before
MessageQueueSelector s = (mqs, m, arg) -> keyQueueMap.get(arg); // null on miss
// after
MessageQueueSelector s = (mqs, m, arg) -> {
    MessageQueue mq = keyQueueMap.get(arg);
    return mq != null ? mq : mqs.get((arg.hashCode() & Integer.MAX_VALUE) % mqs.size());
};
Defensive patterns

Strategy: validation

Validate before calling

 MessageQueueSelector nonNull = (mqs, m, arg) -> {
    MessageQueue q = rawSelector.select(mqs, m, arg);
    return q != null ? q : mqs.get(ThreadLocalRandom.current().nextInt(mqs.size()));
};

Type guard

 boolean selectsQueue(MessageQueueSelector s, List<MessageQueue> mqs, Message m, Object arg) {
    return s.select(mqs, m, arg) != null; // for pre-flight checks in tests
}

Try / catch

try {
    producer.send(msg, selector, arg);
} catch (MQClientException e) {
    if ("select message queue return null.".equals(e.getMessage())) {
        producer.send(msg); // fallback: default send-path selection
    } else throw e;
}

Prevention

When it happens

Trigger: triggerScenarios

Common situations: commonSituations

Related errors


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