alibaba/canal · error · RuntimeException
pattern tag cannot multi: {}
Error message
pattern tag cannot multi: {} What it means
Thrown by MQUtil.checkTagWithErr when a tag in the supplied varargs list is a 'pattern' tag (matches isPatternTag: contains any character outside [0-9a-zA-Z], e.g. '*' or '.'). The message 'pattern tag cannot multi' means regex/pattern tag matching is not permitted in multi-tag mode. Canal rejects pattern tags because the downstream MQ producer (RocketMQ/Kafka) cannot resolve a regex tag when more than one tag is configured.
Source
Thrown at common/src/main/java/com/alibaba/otter/canal/common/utils/MQUtil.java:93
*
* @param tags
*/
public static void checkTagWithErr(String... tags) {
// 空表示不使用tag
if (null == tags || 0 == tags.length) {
return;
}
// if (1 == tags.length && (null == tags[0] || 0 == tags[0].trim().length())) {
// throw new NullPointerException("tag cannot null");
// }
for (String t : tags) {
if (!checkTag(t)) {
throw new IllegalArgumentException("tag invalid: " + t);
}
if (isPatternTag(t)) {
throw new RuntimeException("pattern tag cannot multi: " + t);
}
}
}
}
View on GitHub (pinned to 87be50e876)
Solutions
- Remove pattern characters ('*', '.') from the tag value(s) so each tag is pure alphanumeric.
- If a single pattern tag is genuinely needed, ensure exactly one tag is passed and review whether the MQ destination supports it (this path still rejects it — use a concrete tag instead).
- Audit the canal.mq.tag / canal.mq.partitionHash / tag-related properties in canal.properties and instance properties for stray wildcards.
Example fix
// before
MQUtil.checkTagWithErr("order", "pay.*");
// after
MQUtil.checkTagWithErr("order", "pay"); Defensive patterns
Strategy: validation
Validate before calling
// Validate tags before invoking checkTagWithErr
import com.alibaba.otter.canal.common.utils.MQUtil;
void assertTagsSafe(String... tags) {
if (tags == null) return;
for (String t : tags) {
if (!MQUtil.checkTag(t)) {
throw new IllegalArgumentException("invalid tag format: " + t);
}
if (MQUtil.isPatternTag(t)) {
throw new IllegalArgumentException(
"pattern tag not allowed in multi-tag mode; use pure alphanumeric: " + t);
}
}
}
// assertTagsSafe(tags); // call before MQUtil.checkTagWithErr(tags) Type guard
// Returns true only when the tag is safe for checkTagWithErr
boolean isSafeTag(String tag) {
return tag != null && tag.matches("^[0-9a-zA-Z]+$");
} Try / catch
try {
MQUtil.checkTagWithErr(tags);
} catch (RuntimeException e) {
// handle config error: strip pattern chars or fail fast with context
throw new IllegalStateException("Invalid canal.mq.tag config: " + e.getMessage(), e);
} Prevention
- Sanitize tag config at startup via isSafeTag before producer init.
- Treat any '*' or '.' in canal.mq.tag as a config smell and reject it during deployment validation.
When it happens
Trigger: Calling MQUtil.checkTagWithErr("orderTag","payTag.*") or any single/varargs call where a tag contains '.', '*', or other non-alphanumeric chars that pass checkTag (which allows [0-9a-zA-Z.*]) but fail isPatternTag (which requires pure [0-9a-zA-Z]).
Common situations: Misconfiguring canal.mq.tag with a wildcard like 'order.*' in a multi-topic/multi-tag deployment; copying a tag expression that works for RocketMQ SQL92 subscription into a producer tag field; config templating that injects '*' as a placeholder.
Related errors
- Start RocketMQ consumer error
- mq get/ack not support concurrent & async ack
- Failed to fetch the data after: {timeout}
- mq not support this method
- KuduMapping.database
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/0842babbcb1b879c.
Report an issue: GitHub.