apache/rocketmq · error · MQClientException

add subscription exception

Error message

add subscription exception

What it means

DefaultMQPullConsumer.addRegisterSubscriptions builds a SubscriptionData via FilterAPI.build(topic, expression, expressionType) and wraps ANY failure in MQClientException('add subscription exception'). The underlying cause is almost always an invalid filter expression: a malformed tag expression, an invalid EXPRESSION_TYPE (only TAG and SQL92 are valid), or a null expression with a non-TAG type. The cause chain (e) carries the real reason from FilterAPI/SubscriptionData.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/consumer/DefaultMQPullConsumer.java:279

        this.registerTopics = withNamespace(registerTopics);
    }

    public Set<SubscriptionData> getRegisterSubscriptions() {
        return registerSubscriptions;
    }

    public void addRegisterSubscriptions(String topic, MessageSelector messageSelector) throws MQClientException {
        try {
            if (messageSelector == null) {
                messageSelector = MessageSelector.byTag(SubscriptionData.SUB_ALL);
            }

            SubscriptionData subscriptionData = FilterAPI.build(withNamespace(topic),
                messageSelector.getExpression(), messageSelector.getExpressionType());

            this.registerSubscriptions.add(subscriptionData);
        } catch (Exception e) {
            throw new MQClientException("add subscription exception", e);
        }
    }

    public void clearRegisterSubscriptions() {
        this.registerSubscriptions.clear();
    }

    /**
     * This method will be removed or it's visibility will be changed in a certain version after April 5, 2020, so
     * please do not use this method.
     */
    @Deprecated
    @Override
    public void sendMessageBack(MessageExt msg, int delayLevel)
        throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
        msg.setTopic(withNamespace(msg.getTopic()));
        this.defaultMQPullConsumerImpl.sendMessageBack(msg, delayLevel, msg.getBrokerName());
    }

View on GitHub (pinned to 293f588571)

Solutions

  1. Read the wrapped cause (e.getCause()) — it states the exact expression error
  2. Use the factories: MessageSelector.byTag("TagA || TagB") or MessageSelector.bySql("a > 5") instead of hand-built selectors
  3. For SQL92, enable and verify broker config enablePropertyFilter=true and use valid SQL92 syntax (comparisons on properties, not tags)
  4. Pass null selector only if you accept SUB_ALL tags; do not mix a null expression with SQL92 type

Example fix

// before
consumer.addRegisterSubscriptions("TopicT", MessageSelector.bySql("tags is 'a' AND")); // malformed SQL92

// after
consumer.addRegisterSubscriptions("TopicT", MessageSelector.bySql("a BETWEEN 1 AND 5"));
Defensive patterns

Strategy: try-catch

Validate before calling

// Prefer factory selectors; sanity-check SQL92 before registering
if (selector != null && "SQL92".equals(selector.getExpressionType())
        && selector.getExpression() == null) {
    throw new IllegalArgumentException("SQL92 selector requires an expression");
}

Try / catch

try {
    consumer.addRegisterSubscriptions(topic, selector);
} catch (MQClientException e) {
    Throwable cause = e.getCause(); // real expression parse error
    log.error("Bad subscription for {}: {}", topic, cause.getMessage());
    // fix expression or fall back to MessageSelector.byTag("*")
}

Prevention

When it happens

Trigger: Calling addRegisterSubscriptions(topic, MessageSelector.bySql("invalid SQL ~~")) — SQL92 parse failure; passing a selector whose expression type string is neither 'TAG' nor 'SQL92'; a tag expression like 'a && ' that fails tag parsing.

Common situations: Switching a consumer from tag filtering to SQL92 filtering with a syntax error; copy-pasting SQL92 expressions into a TAG selector; building MessageSelector manually with a wrong expressionType constant instead of byTag/bySql factories.

Related errors


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