apache/rocketmq · error · MQClientException
subscription exception
Error message
subscription exception
What it means
Thrown by copySubscription() during start() when building SubscriptionData for any of the registered topics (registerTopics) throws. Each topic is compiled through FilterAPI.buildSubscriptionData(topic, SUB_ALL); any failure — typically a malformed topic name — surfaces wrapped as 'subscription exception'.
Source
Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPullConsumerImpl.java:829
if (this.defaultMQPullConsumer.getConsumerTimeoutMillisWhenSuspend() < this.defaultMQPullConsumer.getBrokerSuspendMaxTimeMillis()) {
throw new MQClientException(
"Long polling mode, the consumer consumerTimeoutMillisWhenSuspend must greater than brokerSuspendMaxTimeMillis"
+ FAQUrl.suggestTodo(FAQUrl.CLIENT_PARAMETER_CHECK_URL),
null);
}
}
private void copySubscription() throws MQClientException {
try {
Set<String> registerTopics = this.defaultMQPullConsumer.getRegisterTopics();
if (registerTopics != null) {
for (final String topic : registerTopics) {
SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(topic, SubscriptionData.SUB_ALL);
this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
}
}
} catch (Exception e) {
throw new MQClientException("subscription exception", e);
}
}
public void updateConsumeOffset(MessageQueue mq, long offset) throws MQClientException {
this.isRunning();
this.offsetStore.updateOffset(mq, offset, false);
}
public MessageExt viewMessage(String topic, String msgId)
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
this.isRunning();
return this.mQClientFactory.getMQAdminImpl().viewMessage(topic, msgId);
}
public void registerFilterMessageHook(final FilterMessageHook hook) {
this.filterMessageHookList.add(hook);
log.info("register FilterMessageHook Hook, {}", hook.hookName());
}View on GitHub (pinned to 293f588571)
Solutions
- Inspect the cause chain — the wrapped exception names the offending topic and reason
- Sanitize/validate topic names against Validators.topicValidator (regex ^[%|a-zA-Z0-9_-]+$) before registering them
- Trim whitespace from topic strings sourced from config files or env vars
Example fix
// before
consumer.setRegisterTopics(Sets.newHashSet("order topic", "")); // invalid
consumer.start();
// after
Set<String> topics = rawTopics.stream()
.map(String::trim)
.filter(t -> t.matches("[%|a-zA-Z0-9_-]+"))
.collect(Collectors.toSet());
consumer.setRegisterTopics(topics);
consumer.start(); Defensive patterns
Strategy: validation
Validate before calling
for (String t : topics) {
if (!t.trim().matches("[%|a-zA-Z0-9_-]+") || t.length() > 127)
throw new IllegalArgumentException("invalid topic: " + t);
} Try / catch
catch (MQClientException e) { log.error("subscription failed, cause:", e.getCause()); } Prevention
- Trim and validate topic names before setRegisterTopics
- Reject empty or over-long topics at config load
When it happens
Trigger: Calling setRegisterTopics(...) with a topic containing illegal characters or violating length limits before start(); a topic string with whitespace, empty string, or characters FilterAPI's TopicFilter rejects (valid pattern is ^[%|a-zA-Z0-9_-]+$ with length <= 127 in Validators).
Common situations: Topic names constructed from user input or environment variables without validation; trailing whitespace or newline in topic strings read from config files; topics exceeding the 127-char limit after concatenating prefixes.
Related errors
- topic list is empty.
- The specified topic is blank
- The specified topic is longer than topic max length %d.
- The specified topic[%s] contains illegal characters, allowin
- The topic[%s] is conflict with system topic.
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/320aeb40d6df7b16.
Report an issue: GitHub.