apache/rocketmq · error · MQClientException
The producer group[{producerGroup}] has been created before,
Error message
The producer group[{producerGroup}] has been created before, specify another name please. What it means
MQClientException thrown from DefaultMQProducerImpl.start() when registerProducer(group, this) returns false, i.e. a producer with the same group name is already registered in this JVM's MQClientInstance (keyed by clientId). RocketMQ requires producer group names to be unique within a client instance because the group maps 1:1 to the producer implementation inside the shared factory. The companion FAQ link points at the duplicate group name page.
Source
Thrown at client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java:261
public void start(final boolean startFactory) throws MQClientException {
switch (this.serviceState) {
case CREATE_JUST:
this.serviceState = ServiceState.START_FAILED;
this.checkConfig();
if (!this.defaultMQProducer.getProducerGroup().equals(MixAll.CLIENT_INNER_PRODUCER_GROUP)) {
this.defaultMQProducer.changeInstanceNameToPID();
}
this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultMQProducer, rpcHook);
defaultMQProducer.initProduceAccumulator();
boolean registerOK = mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this);
if (!registerOK) {
this.serviceState = ServiceState.CREATE_JUST;
throw new MQClientException("The producer group[" + this.defaultMQProducer.getProducerGroup()
+ "] has been created before, specify another name please." + FAQUrl.suggestTodo(FAQUrl.GROUP_NAME_DUPLICATE_URL),
null);
}
if (startFactory) {
mQClientFactory.start();
}
this.initTopicRoute();
this.mqFaultStrategy.startDetector();
log.info("the producer [{}] start OK. sendMessageWithVIPChannel={}", this.defaultMQProducer.getProducerGroup(),
this.defaultMQProducer.isSendMessageWithVIPChannel());
this.serviceState = ServiceState.RUNNING;
break;
case RUNNING:
case START_FAILED:View on GitHub (pinned to 293f588571)
Solutions
- Use one shared DefaultMQProducer per group name per JVM (cache/singleton it) instead of creating new instances
- If you truly need multiple producers, give each a distinct producerGroup name
- Ensure producer.shutdown() fully ran (it unregisters the group) before creating a replacement with the same group
- Set a distinct instanceName/unitName on the ClientConfig so each producer gets a different MQClientInstance if isolation is intended
Example fix
// before
DefaultMQProducer p = new DefaultMQProducer("order-producer");
p.start(); // called again elsewhere with same group -> exception
// after
private static volatile DefaultMQProducer shared;
if (shared == null) { shared = new DefaultMQProducer("order-producer"); shared.start(); } Defensive patterns
Strategy: validation
Validate before calling
private final Set<String> registeredGroups = ConcurrentHashMap.newKeySet();
public DefaultMQProducer getOrCreate(String group) throws MQClientException {
if (!registeredGroups.add(group)) {
return existingProducers.get(group); // reuse, don't create duplicate
}
DefaultMQProducer p = new DefaultMQProducer(group);
p.start();
existingProducers.put(group, p);
return p;
} Try / catch
try {
producer.start();
} catch (MQClientException e) {
if (e.getMessage() != null && e.getMessage().contains("has been created before")) {
return existingProducerFor(group); // reuse the already-registered instance
}
throw e;
} Prevention
- Cache producers by group name in a registry/map; never construct a second producer for the same group in one JVM
- Wrap producers in a singleton bean (Spring) so lifecycle is managed once
- Always call shutdown() in @PreDestroy / finally so group names are released before re-creation
- Give producers distinct instanceName via setInstanceName when intentional isolation is needed
When it happens
Trigger: Creating and starting two DefaultMQProducer instances with the same producerGroup and the same clientId (same unit name / instance settings) in one JVM; starting a producer, shutting it down incompletely, and starting a new one with the same group before unregistration completes; re-start() after a partially failed start.
Common situations: Singleton wrappers (Spring beans, connection pools) that lazily create a producer per request without caching by group name; code that calls producer.start() in a loop or in @PostConstruct of a prototype-scoped bean; tests that build a new producer per test method but share the JVM and instance name.
Related errors
- The producer service state not OK, maybe started once, {serv
- The producer service state not OK, {serviceState}
- 13
- Sending message to topic[%s] is forbidden.
- sendMessage call timeout
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/8b4070fab9bc242b.
Report an issue: GitHub.