apache/rocketmq · error · MQClientException

The PullConsumer service state not OK, maybe started once,

Error message

The PullConsumer service state not OK, maybe started once, 

What it means

MQClientException thrown by DefaultLitePullConsumerImpl.start() when the service state is RUNNING (already started), START_FAILED, or SHUTDOWN_ALREADY — i.e. start() was called on an instance that cannot transition from CREATE_JUST again. The message appends the current state and a FAQ URL for client service state issues.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultLitePullConsumerImpl.java:321

                startScheduleTask();

                this.serviceState = ServiceState.RUNNING;

                log.info("the consumer [{}] start OK", this.defaultLitePullConsumer.getConsumerGroup());

                try {
                    operateAfterRunning();
                } catch (Exception e) {
                    shutdown();
                    throw e;
                }

                break;
            case RUNNING:
            case START_FAILED:
            case SHUTDOWN_ALREADY:
                throw new MQClientException("The PullConsumer service state not OK, maybe started once, "
                    + this.serviceState
                    + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
                    null);
            default:
                break;
        }
    }

    private void initScheduledThreadPoolExecutor() {
        this.scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(
                this.defaultLitePullConsumer.getPullThreadNums(),
                new ThreadFactoryImpl("PullMsgThread-" + this.defaultLitePullConsumer.getConsumerGroup())
        );
    }

    private void initMQClientFactory() throws MQClientException {
        this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultLitePullConsumer, this.rpcHook);
        boolean registerOK = mQClientFactory.registerConsumer(this.defaultLitePullConsumer.getConsumerGroup(), this);

View on GitHub (pinned to 293f588571)

Solutions

  1. Call start() exactly once per instance, guarded by your own started flag or framework singleton lifecycle
  2. To restart, build a new DefaultLitePullConsumer — instances are not reusable after shutdown
  3. If the first start() threw, do not retry start() on the same object; fix the root cause and recreate
  4. Audit Spring configs for duplicate init methods on the same consumer bean

Example fix

// before: reconnect loop reuses instance
if (broken) { consumer.shutdown(); consumer.start(); } // state not OK

// after: recreate the instance
if (broken) {
    consumer.shutdown();
    consumer = buildConsumer(); // new DefaultLitePullConsumer with same config
    consumer.start();
}
Defensive patterns

Strategy: validation

Validate before calling

// wrap start with an idempotent guard
private final AtomicBoolean started = new AtomicBoolean(false);
public synchronized void ensureStarted() {
    if (started.compareAndSet(false, true)) {
        consumer.start();
    }
}

Try / catch

try {
    consumer.start();
} catch (MQClientException e) {
    if (e.getMessage() != null && e.getMessage().contains("service state not OK")) {
        // duplicate start: safe to ignore only if already RUNNING; otherwise recreate instance
    } else throw e;
}

Prevention

When it happens

Trigger: Calling consumer.start() twice; calling start() again after a failed start (state START_FAILED); calling start() on an instance previously shut down (SHUTDOWN_ALREADY). Restart logic in health checks or reconnect loops commonly triggers it.

Common situations: Framework lifecycle hooks (Spring @PostConstruct plus a manual init) both calling start(); retry wrappers that call start() after shutdown to 'reconnect' a pull consumer; ignoring a first start() exception and retrying start() on the poisoned instance.

Related errors


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