apache/rocketmq · error · MQClientException

consumeThreadMin ({min}) is larger than consumeThreadMax ({m

Error message

consumeThreadMin ({min}) is larger than consumeThreadMax ({max})

What it means

checkConfig() enforces the invariant consumeThreadMin <= consumeThreadMax for the consumer's thread pool. Each bound individually passed the [1,1000] check, but min exceeds max, which would produce an invalid executor configuration.

Source

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

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

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

        // consumeThreadMin can't be larger than consumeThreadMax
        if (this.defaultMQPushConsumer.getConsumeThreadMin() > this.defaultMQPushConsumer.getConsumeThreadMax()) {
            throw new MQClientException(
                "consumeThreadMin (" + this.defaultMQPushConsumer.getConsumeThreadMin() + ") "
                    + "is larger than consumeThreadMax (" + this.defaultMQPushConsumer.getConsumeThreadMax() + ")",
                null);
        }

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

        // pullThresholdForQueue
        if (this.defaultMQPushConsumer.getPullThresholdForQueue() < 1 || this.defaultMQPushConsumer.getPullThresholdForQueue() > 65535) {
            throw new MQClientException(
                "pullThresholdForQueue Out of range [1, 65535]"

View on GitHub (pinned to 293f588571)

Solutions

  1. Make consumeThreadMin <= consumeThreadMax (commonly equal, e.g. both 20)
  2. Define the pair once in a single config block (min, max together) so they cannot drift
  3. Add a startup assertion in your consumer factory: Preconditions.checkArgument(min <= max)

Example fix

// before
consumer.setConsumeThreadMin(64);
consumer.setConsumeThreadMax(20); // min > max

// after
consumer.setConsumeThreadMin(20);
consumer.setConsumeThreadMax(64);
Defensive patterns

Strategy: validation

Validate before calling

if (config.getConsumeThreadMin() > config.getConsumeThreadMax())
    throw new IllegalArgumentException("consumeThreadMin > consumeThreadMax");
consumer.setConsumeThreadMin(config.getConsumeThreadMin());
consumer.setConsumeThreadMax(config.getConsumeThreadMax());

Prevention

When it happens

Trigger: Setting min larger than max (e.g. min=64, max=20); updating only one of the two in config so previously-consistent values now cross; environment-specific overrides changing max but not min.

Common situations: Different files/environments setting the pair inconsistently; renaming config keys so one side falls back to default while the other keeps an old value.

Related errors


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