apache/rocketmq · error · MQClientException
The specified topic[%s] contains illegal characters, allowin
Error message
The specified topic[%s] contains illegal characters, allowing only %s
What it means
Validators.checkTopic rejects topics containing characters outside ^[%|a-zA-Z0-9_-]+$ (checked via isTopicOrGroupIllegal). Dots, colons, spaces, slashes, and unicode are illegal; '%' is allowed because system topics like %RETRY% and %DLQ% use it.
Source
Thrown at client/src/main/java/org/apache/rocketmq/client/Validators.java:106
String lmqPath = msg.getUserProperty(MessageConst.PROPERTY_INNER_MULTI_DISPATCH);
if (StringUtils.contains(lmqPath, File.separator)) {
throw new MQClientException(ResponseCode.MESSAGE_ILLEGAL,
"INNER_MULTI_DISPATCH " + lmqPath + " can not contains " + File.separator + " character");
}
}
public static void checkTopic(String topic) throws MQClientException {
if (UtilAll.isBlank(topic)) {
throw new MQClientException("The specified topic is blank", null);
}
if (topic.length() > TOPIC_MAX_LENGTH) {
throw new MQClientException(
String.format("The specified topic is longer than topic max length %d.", TOPIC_MAX_LENGTH), null);
}
if (isTopicOrGroupIllegal(topic)) {
throw new MQClientException(String.format(
"The specified topic[%s] contains illegal characters, allowing only %s", topic,
"^[%|a-zA-Z0-9_-]+$"), null);
}
}
public static void isSystemTopic(String topic) throws MQClientException {
if (TopicValidator.isSystemTopic(topic)) {
throw new MQClientException(
String.format("The topic[%s] is conflict with system topic.", topic), null);
}
}
public static void isNotAllowedSendTopic(String topic) throws MQClientException {
if (TopicValidator.isNotAllowedSendTopic(topic)) {
throw new MQClientException(
String.format("Sending message to topic[%s] is forbidden.", topic), null);
}
}View on GitHub (pinned to 293f588571)
Solutions
- Normalize topic names to letters, digits, '-', '_' — replace '.' with '-' or '_'.
- Add a startup regex check on configured topics: topic.matches("^[%|a-zA-Z0-9_-]+$").
- Trim whitespace when topics come from user or config input.
Example fix
// before String topic = "order.created.v2"; // after String topic = "order-created-v2";
Defensive patterns
Strategy: validation
Validate before calling
static boolean legalTopicName(String t) {
return t != null && t.matches("^[%|a-zA-Z0-9_-]+$");
} Prevention
- Normalize dotted event names to hyphens at the topic factory.
- Validate all configured topics with the regex once at startup.
When it happens
Trigger: Creating/sending with a topic like 'order.created.v2' (dot), 'app:orders' (colon), or '订单' (unicode); topics derived from URLs or free-form strings.
Common situations: Porting Kafka-style dotted topic names; using domain event names verbatim ('order.created'); copy-paste introducing invisible whitespace.
Related errors
- The topic[%s] is conflict with system topic.
- topic list is empty.
- the specified group[%s] contains illegal characters, allowin
- The specified topic is blank
- The specified topic is longer than topic max length %d.
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/4e653d647cadc7fe.
Report an issue: GitHub.