apache/rocketmq · error · MQClientException

mq is null

Error message

mq is null

What it means

DefaultMQPullConsumerImpl.getSubscriptionData (the string-expression overload used by pull(...)) throws MQClientException("mq is null") when the MessageQueue argument is null. The subscription is built from mq.getTopic(), so a null queue cannot produce a subscription and the pull is aborted before any request is sent.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPullConsumerImpl.java:204

        return this.pullSyncImpl(mq, subscriptionData, offset, maxNums, false, timeout);
    }

    public PullResult pull(MessageQueue mq, MessageSelector messageSelector, long offset, int maxNums)
        throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
        return pull(mq, messageSelector, offset, maxNums, this.defaultMQPullConsumer.getConsumerPullTimeoutMillis());
    }

    public PullResult pull(MessageQueue mq, MessageSelector messageSelector, long offset, int maxNums, long timeout)
        throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
        SubscriptionData subscriptionData = getSubscriptionData(mq, messageSelector);
        return this.pullSyncImpl(mq, subscriptionData, offset, maxNums, false, timeout);
    }

    private SubscriptionData getSubscriptionData(MessageQueue mq, String subExpression)
        throws MQClientException {

        if (null == mq) {
            throw new MQClientException("mq is null", null);
        }

        try {
            return FilterAPI.buildSubscriptionData(mq.getTopic(), subExpression);
        } catch (Exception e) {
            throw new MQClientException("parse subscription error", e);
        }
    }

    private SubscriptionData getSubscriptionData(MessageQueue mq, MessageSelector messageSelector)
        throws MQClientException {

        if (null == mq) {
            throw new MQClientException("mq is null", null);
        }

        try {
            return FilterAPI.build(mq.getTopic(),

View on GitHub (pinned to 293f588571)

Solutions

  1. Null-check mq before pull; assert the queue collection is non-empty first
  2. When iterating fetched queues, handle the empty-set case instead of indexing into it

Example fix

// before
Set<MessageQueue> qs = consumer.fetchMessageQueues(topic);
PullResult r = consumer.pull(qs.isEmpty() ? null : qs.iterator().next(), "*", 0, 1, 3000);

// after
Set<MessageQueue> qs = consumer.fetchMessageQueues(topic);
if (qs.isEmpty()) throw new IllegalStateException("no queues for " + topic);
PullResult r = consumer.pull(qs.iterator().next(), "*", 0, 1, 3000);
Defensive patterns

Strategy: validation

Validate before calling

if (mq == null) throw new IllegalArgumentException("queue not resolved for pull");
PullResult r = consumer.pull(mq, subExpr, offset, maxNums, timeout);

Prevention

When it happens

Trigger: consumer.pull(null, subExpression, offset, maxNums, timeout); passing a queue looked up from a Map/Set that returned null.

Common situations: Queue selected from fetchMessageQueues() result that is empty; queue variable from a failed deserialization of a stored offset entry.

Related errors


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