apache/rocketmq · error · MQClientException

popBatchNums Out of range [1, 32]

Error message

popBatchNums Out of range [1, 32]

What it means

Thrown during push-consumer startup when popBatchNums is outside [1, 32]. popBatchNums controls how many messages the broker returns per POP request in POP consumption mode. The upper bound of 32 matches broker-side POP limits, and at least one message per pop is required.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPushConsumerImpl.java:1205

        if (this.defaultMQPushConsumer.getPullBatchSize() < 1 || this.defaultMQPushConsumer.getPullBatchSize() > 1024) {
            throw new MQClientException(
                "pullBatchSize Out of range [1, 1024]"
                    + FAQUrl.suggestTodo(FAQUrl.CLIENT_PARAMETER_CHECK_URL),
                null);
        }

        // popInvisibleTime
        if (this.defaultMQPushConsumer.getPopInvisibleTime() < MIN_POP_INVISIBLE_TIME
            || this.defaultMQPushConsumer.getPopInvisibleTime() > MAX_POP_INVISIBLE_TIME) {
            throw new MQClientException(
                "popInvisibleTime Out of range [" + MIN_POP_INVISIBLE_TIME + ", " + MAX_POP_INVISIBLE_TIME + "]"
                    + FAQUrl.suggestTodo(FAQUrl.CLIENT_PARAMETER_CHECK_URL),
                null);
        }

        // popBatchNums
        if (this.defaultMQPushConsumer.getPopBatchNums() <= 0 || this.defaultMQPushConsumer.getPopBatchNums() > 32) {
            throw new MQClientException(
                "popBatchNums Out of range [1, 32]"
                    + FAQUrl.suggestTodo(FAQUrl.CLIENT_PARAMETER_CHECK_URL),
                null);
        }
    }

    private void copySubscription() throws MQClientException {
        try {
            Map<String, String> sub = this.defaultMQPushConsumer.getSubscription();
            if (sub != null) {
                for (final Map.Entry<String, String> entry : sub.entrySet()) {
                    final String topic = entry.getKey();
                    final String subString = entry.getValue();
                    SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(topic, subString);
                    this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
                }
            }

View on GitHub (pinned to 293f588571)

Solutions

  1. Set popBatchNums to a value in [1, 32] (default 32 is not configurable beyond this)
  2. Keep popBatchNums aligned with the listener's processing capacity so popped messages do not time out invisibility
  3. For more POP throughput, increase consumer concurrency or use more consumers rather than exceeding 32

Example fix

// before
consumer.setPopBatchNums(64); // > 32, rejected at start()
// after
consumer.setPopBatchNums(32); // maximum allowed per pop request
Defensive patterns

Strategy: validation

Validate before calling

int v = consumer.getPopBatchNums();
if (v < 1 || v > 32) throw new IllegalArgumentException("popBatchNums must be in [1,32]: " + v);
consumer.start();

Try / catch

catch (MQClientException e) { if (e.getMessage().contains("popBatchNums")) throw new ConfigException(e); throw e; }

Prevention

When it happens

Trigger: Calling consumer.setPopBatchNums(n) with n <= 0 or n > 32, then consumer.start(). Only meaningful when the consumer actually runs in POP mode (e.g. a Lite consumer / assign mode), but the check runs for every push consumer start.

Common situations: Tuning popBatchNums above 32 while chasing throughput; leaving an unset numeric field that deserializes to 0 from a config source; confusing popBatchNums with pullBatchSize (max 1024) and copying a value between them.

Related errors


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