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
- Call producer.start() once before any send and verify it succeeded (no exception)
- 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
- If state is START_FAILED, fix the underlying start error (see its exception) and create a fresh producer instance
- 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
- Call start() in @PostConstruct and shutdown() in @PreDestroy of the same singleton bean
- Stop worker threads before producer.shutdown() (SmartLifecycle phase ordering)
- Add a running-state guard in send wrappers for a clearer failure than the generic message
- Never send from threads that can outlive the producer without an explicit closed flag
When it happens
Trigger: triggerScenarios
Common situations: commonSituations
Related errors
- sendMessage call timeout
- The producer group[{producerGroup}] has been created before,
- The producer service state not OK, maybe started once, {serv
- sendDefaultImpl call timeout
- call timeout
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/bd54990070477c8b.
Report an issue: GitHub.