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

  1. Remove pattern characters ('*', '.') from the tag value(s) so each tag is pure alphanumeric.
  2. 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).
  3. 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

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


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/0842babbcb1b879c. Report an issue: GitHub.