apache/rocketmq · error · MQClientException

parse subscription error

Error message

parse subscription error

What it means

The catch block of getSubscriptionData wraps any exception from FilterAPI.buildSubscriptionData(topic, subExpression) as MQClientException("parse subscription error", cause). buildSubscriptionData parses a TAG expression; malformed expressions (illegal characters, unbalanced parts after splitting on '||') raise the underlying exception which is rethrown here.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPullConsumerImpl.java:210

    }

    public PullResult pull(MessageQueue mq, MessageSelector messageSelector, long offset, int maxNums, long timeout)
        throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
        SubscriptionData subscriptionData = getSubscriptionData(mq, messageSelector);
        return this.pullSyncImpl(mq, subscriptionData, offset, maxNums, false, timeout);
    }

    private SubscriptionData getSubscriptionData(MessageQueue mq, String subExpression)
        throws MQClientException {

        if (null == mq) {
            throw new MQClientException("mq is null", null);
        }

        try {
            return FilterAPI.buildSubscriptionData(mq.getTopic(), subExpression);
        } catch (Exception e) {
            throw new MQClientException("parse subscription error", e);
        }
    }

    private SubscriptionData getSubscriptionData(MessageQueue mq, MessageSelector messageSelector)
        throws MQClientException {

        if (null == mq) {
            throw new MQClientException("mq is null", null);
        }

        try {
            return FilterAPI.build(mq.getTopic(),
                messageSelector.getExpression(), messageSelector.getExpressionType());
        } catch (Exception e) {
            throw new MQClientException("parse subscription error", e);
        }
    }

View on GitHub (pinned to 293f588571)

Solutions

  1. Validate/normalize the expression: non-empty operands around each '||', no whitespace inside a tag unless intended
  2. Call e.getCause() to see the precise parse failure from FilterAPI
  3. Build expressions from a validated tag vocabulary rather than raw concatenation

Example fix

// before
String expr = String.join("||", tags); // may end with '||' if a tag is empty
consumer.pull(mq, expr, 0, 32, 3000);

// after
String expr = tags.stream().filter(t -> t != null && !t.trim().isEmpty()).collect(Collectors.joining("||"));
consumer.pull(mq, expr, 0, 32, 3000);
Defensive patterns

Strategy: validation

Validate before calling

String expr = Arrays.stream(subExpr.split("\\|\\|"))
    .map(String::trim)
    .filter(s -> !s.isEmpty())
    .collect(Collectors.joining("||"));
if (expr.isEmpty()) expr = "*";

Try / catch

try {
    consumer.pull(mq, expr, offset, maxNums, timeout);
} catch (MQClientException e) {
    if (e.getCause() != null) {
        // parse failure — fix expression, never retry unchanged
    }
}

Prevention

When it happens

Trigger: consumer.pull(mq, "TAG A ||", ...) with a trailing separator; subExpression containing characters illegal in a tag; expression built by string concatenation with a stray '||'.

Common situations: User-supplied tag filters; dynamically assembled OR-expressions where an operand is empty.

Related errors


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