apache/rocketmq · error · MQClientException

The consumer is not in running status, {serviceState}

Error message

The consumer is not in running status, {serviceState}

What it means

DefaultMQPullConsumerImpl.isRunning() throws MQClientException("The consumer is not in running status, ...") whenever an administrative operation (createTopic, fetchConsumeOffset, fetchMessageQueuesInBalance, pull, etc.) is invoked while serviceState != RUNNING. RocketMQ pull consumers must be start()ed before any of these APIs touch the client factory, offset store, or network.

Source

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

    }

    public void registerConsumeMessageHook(final ConsumeMessageHook hook) {
        this.consumeMessageHookList.add(hook);
        log.info("register consumeMessageHook Hook, {}", hook.hookName());
    }

    public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
        createTopic(key, newTopic, queueNum, 0);
    }

    public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
        this.isRunning();
        this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag, null);
    }

    private void isRunning() throws MQClientException {
        if (this.serviceState != ServiceState.RUNNING) {
            throw new MQClientException("The consumer is not in running status, "
                + this.serviceState
                + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
                null);
        }
    }

    public long fetchConsumeOffset(MessageQueue mq, boolean fromStore) throws MQClientException {
        this.isRunning();
        return this.offsetStore.readOffset(mq, fromStore ? ReadOffsetType.READ_FROM_STORE : ReadOffsetType.MEMORY_FIRST_THEN_STORE);
    }

    public Set<MessageQueue> fetchMessageQueuesInBalance(String topic) throws MQClientException {
        this.isRunning();
        if (null == topic) {
            throw new IllegalArgumentException("topic is null");
        }

        ConcurrentMap<MessageQueue, ProcessQueue> mqTable = this.rebalanceImpl.getProcessQueueTable();

View on GitHub (pinned to 293f588571)

Solutions

  1. Ensure consumer.start() completed successfully before any admin/pull call
  2. Guard calls with consumer.isRunning() where the API exposes it, or track started state yourself
  3. Never reuse a consumer instance after shutdown() — create a new one

Example fix

// before
DefaultMQPullConsumer c = new DefaultMQPullConsumer(gid);
long off = c.fetchConsumeOffset(mq, false);

// after
DefaultMQPullConsumer c = new DefaultMQPullConsumer(gid);
c.start();
long off = c.fetchConsumeOffset(mq, false);
Defensive patterns

Strategy: validation

Try / catch

try {
    long off = consumer.fetchConsumeOffset(mq, false);
} catch (MQClientException e) {
    if (e.getMessage().contains("not in running status")) {
        // start() not called or shutdown happened — fix lifecycle, do not retry
    }
}

Prevention

When it happens

Trigger: Calling consumer.fetchConsumeOffset(mq, false) or pull(...) before consumer.start(); calling after shutdown().

Common situations: Initialization-order bug (querying offsets in a constructor/@PostConstruct that runs before the start method); using a consumer after calling shutdown() in a cleanup path; failed start() leaving state CREATE_JUST.

Related errors


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