{"record":{"id":"0842babbcb1b879c","repo":"alibaba/canal","slug":"pattern-tag-cannot-multi","errorCode":null,"errorMessage":"pattern tag cannot multi: {}","messagePattern":"pattern tag cannot multi: (.+?)","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/alibaba/otter/canal/common/utils/MQUtil.java","lineNumber":93,"sourceCode":"     *\n     * @param tags\n     */\n    public static void checkTagWithErr(String... tags) {\n        // 空表示不使用tag\n        if (null == tags || 0 == tags.length) {\n            return;\n        }\n\n//        if (1 == tags.length && (null == tags[0] || 0 == tags[0].trim().length())) {\n//            throw new NullPointerException(\"tag cannot null\");\n//        }\n\n        for (String t : tags) {\n            if (!checkTag(t)) {\n                throw new IllegalArgumentException(\"tag invalid: \" + t);\n            }\n            if (isPatternTag(t)) {\n                throw new RuntimeException(\"pattern tag cannot multi: \" + t);\n            }\n        }\n    }\n}\n","sourceCodeStart":75,"sourceCodeEnd":98,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/common/src/main/java/com/alibaba/otter/canal/common/utils/MQUtil.java#L75-L98","documentation":"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.","triggerScenarios":"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]).","commonSituations":"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.","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."],"exampleFix":"// before\nMQUtil.checkTagWithErr(\"order\", \"pay.*\");\n// after\nMQUtil.checkTagWithErr(\"order\", \"pay\");","handlingStrategy":"validation","validationCode":"// Validate tags before invoking checkTagWithErr\nimport com.alibaba.otter.canal.common.utils.MQUtil;\n\nvoid assertTagsSafe(String... tags) {\n    if (tags == null) return;\n    for (String t : tags) {\n        if (!MQUtil.checkTag(t)) {\n            throw new IllegalArgumentException(\"invalid tag format: \" + t);\n        }\n        if (MQUtil.isPatternTag(t)) {\n            throw new IllegalArgumentException(\n                \"pattern tag not allowed in multi-tag mode; use pure alphanumeric: \" + t);\n        }\n    }\n}\n// assertTagsSafe(tags);  // call before MQUtil.checkTagWithErr(tags)","typeGuard":"// Returns true only when the tag is safe for checkTagWithErr\nboolean isSafeTag(String tag) {\n    return tag != null && tag.matches(\"^[0-9a-zA-Z]+$\");\n}","tryCatchPattern":"try {\n    MQUtil.checkTagWithErr(tags);\n} catch (RuntimeException e) {\n    // handle config error: strip pattern chars or fail fast with context\n    throw new IllegalStateException(\"Invalid canal.mq.tag config: \" + e.getMessage(), e);\n}","preventionTips":["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."],"tags":["mq","config-validation","rocketmq","tag"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}