apache/rocketmq · error · MQClientException

The producer service state not OK, {serviceState}

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.

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)

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.