apache/rocketmq · error · MQClientException

The producer service state not OK

Error message

The producer service state not OK, {serviceState}

What it means

MQClientException thrown by DefaultMQProducerImpl.makeSureStateOK() from the head of nearly every public producer API (send, sendOneway, createTopic, fetchPublishMessageQueues, searchOffset, invokeMessageQueueSelector, ...). It fires whenever serviceState != RUNNING - producer not started, start failed, or already shut down. It is the generic 'you forgot start() (or already shut down)' guard for all send-side operations.

Solutions

  1. Call producer.start() once before any send and verify it succeeded (no exception)
  2. Gate background senders on application lifecycle (stop worker threads before producer.shutdown(); e.g. @PreDestroy ordering, SmartLifecycle) with a volatile 'closed' flag checked before send
  3. If state is START_FAILED, fix the underlying start error (see its exception) and create a fresh producer instance
  4. Wrap send paths with an isRunning()/state check or use a small guard method to fail with a clearer message than the generic one

Example fix

// before
DefaultMQProducer p = new DefaultMQProducer("g");
p.send(msg); // throws: not started
// after
DefaultMQProducer p = new DefaultMQProducer("g");
p.start();
if (!closed) { p.send(msg); }
Defensive patterns

Strategy: try-catch

Validate before calling

 private volatile boolean closed = false;
@PreDestroy void close() { closed = true; producer.shutdown(); }
public void sendSafe(Message m) throws MQClientException {
    if (closed) throw new IllegalStateException("producer shut down");
    producer.send(m);
}

Try / catch

try {
    producer.send(msg);
} catch (MQClientException e) {
    if (e.getMessage() != null && e.getMessage().contains("service state not OK")) {
        // producer not started or already shut down - lifecycle bug, not a broker issue
        throw new IllegalStateException("Producer lifecycle misuse: " + e.getMessage(), e);
    }
    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/bd54990070477c8b. Report an issue: GitHub.

Appendix: source

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

    public boolean isUnitMode() {
        return this.defaultMQProducer.isUnitMode();
    }

    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.makeSureStateOK();
        Validators.checkTopic(newTopic);
        Validators.isSystemTopic(newTopic);

        this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag, null);
    }

    private void makeSureStateOK() throws MQClientException {
        if (this.serviceState != ServiceState.RUNNING) {
            throw new MQClientException("The producer service state not OK, "
                + this.serviceState
                + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
                null);
        }
    }

    public List<MessageQueue> fetchPublishMessageQueues(String topic) throws MQClientException {
        this.makeSureStateOK();
        return this.mQClientFactory.getMQAdminImpl().fetchPublishMessageQueues(topic);
    }

    public long searchOffset(MessageQueue mq, long timestamp) throws MQClientException {
        this.makeSureStateOK();
        return this.mQClientFactory.getMQAdminImpl().searchOffset(mq, timestamp);
    }

    public long maxOffset(MessageQueue mq) throws MQClientException {
        this.makeSureStateOK();

View on GitHub (pinned to 293f588571)