apache/rocketmq · error · MQClientException

subscribe exception

Error message

subscribe exception

What it means

MQClientException thrown by DefaultLitePullConsumerImpl.subscribe (both overloads) as a catch-all wrapper: any exception raised inside the try block while subscribing is rethrown with the generic message 'subscribe exception' and the original as cause. The most common real cause is FilterAPI.buildSubscriptionData rejecting an invalid subscription expression (bad SQL92/tag syntax), but any failure (including the empty-topic IllegalArgumentException) surfaces this way.

Source

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

            setSubscriptionType(SubscriptionType.SUBSCRIBE);
            SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(topic, subExpression);
            this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
            this.defaultLitePullConsumer.setMessageQueueListener(new MessageQueueListener() {
                @Override
                public void messageQueueChanged(String topic, Set<MessageQueue> mqAll, Set<MessageQueue> mqDivided) {
                    // First, update the assign queue
                    updateAssignQueueAndStartPullTask(topic, mqAll, mqDivided);
                    // run custom listener
                    messageQueueListener.messageQueueChanged(topic, mqAll, mqDivided);
                }
            });
            assignedMessageQueue.setRebalanceImpl(this.rebalanceImpl);
            if (serviceState == ServiceState.RUNNING) {
                this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
                updateTopicSubscribeInfoWhenSubscriptionChanged();
            }
        } catch (Exception e) {
            throw new MQClientException("subscribe exception", e);
        }
    }

    public synchronized void subscribe(String topic, String subExpression) throws MQClientException {
        try {
            if (topic == null || "".equals(topic)) {
                throw new IllegalArgumentException("Topic can not be null or empty.");
            }
            setSubscriptionType(SubscriptionType.SUBSCRIBE);
            SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(topic, subExpression);
            this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
            this.defaultLitePullConsumer.setMessageQueueListener(new MessageQueueListenerImpl());
            assignedMessageQueue.setRebalanceImpl(this.rebalanceImpl);
            if (serviceState == ServiceState.RUNNING) {
                this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
                updateTopicSubscribeInfoWhenSubscriptionChanged();
            }
        } catch (Exception e) {

View on GitHub (pinned to 293f588571)

Solutions

  1. Always inspect e.getCause() — it names the actual broken input
  2. Fix the subscription expression: valid tag syntax like "TAGA || TAGB", or valid SQL92 like "a > 5 AND b IS NOT NULL" with consumer experimental SQL filter enabled where required
  3. Validate dynamic expressions before passing them to subscribe
  4. Ensure topic/subExpression are non-null and topic non-empty

Example fix

// before
consumer.subscribe("T", "TAGA || "); // trailing operator -> subscribe exception

// after
try {
    consumer.subscribe("T", "TAGA || TAGB");
} catch (MQClientException e) {
    throw new IllegalArgumentException("Bad subscription: " + e.getCause().getMessage(), e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate a tag expression crudely before subscribing
private boolean looksLikeTagExpr(String expr) {
    return expr == null || "*".equals(expr) || expr.matches("[\w ||]+");
}
if (!looksLikeTagExpr(sub)) throw new IllegalArgumentException("bad sub expression: " + sub);

Try / catch

try {
    consumer.subscribe(topic, subExpression);
} catch (MQClientException e) {
    Throwable cause = e.getCause();
    if (cause instanceof MQClientException && cause.getMessage().contains("subscription")) {
        // invalid expression: fix and resubscribe
    } else throw e;
}

Prevention

When it happens

Trigger: subscribe(topic, "TAGA || ") or malformed SQL92 like "a between 1 and" -> buildSubscriptionData throws; empty topic argument; unexpected runtime exceptions during listener wiring. The distinguishing detail lives in e.getCause().

Common situations: Typo'd tag expressions (unbalanced parentheses, bad operators); switching tag filter syntax to SQL92 without enabling sqlFilter support; dynamic expressions built from user input; null subExpression handled differently than expected.

Related errors


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