{"record":{"id":"4e8f8da9f0c04767","repo":"alibaba/canal","slug":"topic-invalid","errorCode":null,"errorMessage":"topic invalid: {}","messagePattern":"topic invalid: (.+?)","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/alibaba/otter/canal/common/utils/MQUtil.java","lineNumber":60,"sourceCode":"        return !tag.matches(\"^[0-9a-zA-Z]+$\");\n    }\n\n    /**\n     * 检查topic有效性\n     *\n     * @param topics\n     */\n    public static void checkTopicWithErr(String... topics) {\n        if (null == topics || 0 == topics.length) {\n            throw new NullPointerException(\"topic cannot null\");\n        }\n\n        if (1 == topics.length) {\n            boolean ok = checkTopic(topics[0]);\n            if (ok) {\n                return;\n            }\n            throw new RuntimeException(\"topic invalid: \" + topics[0]);\n        }\n\n        for (String t : topics) {\n            if (!checkTopic(t)) {\n                throw new IllegalArgumentException(\"topic invalid: \" + t);\n            }\n            if (isPatternTopic(t)) {\n                throw new RuntimeException(\"pattern topic cannot multi: \" + t);\n            }\n        }\n    }\n\n    /**\n     * 检查tag有效性\n     *\n     * @param tags\n     */\n    public static void checkTagWithErr(String... tags) {","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/common/src/main/java/com/alibaba/otter/canal/common/utils/MQUtil.java#L42-L78","documentation":"Thrown by MQUtil.checkTopicWithErr() in the single-topic branch when the topic fails the checkTopic() regex validation. checkTopic() requires topics to match `^[0-9a-z:/.*-]+$` — only lowercase letters, digits, colons, slashes, dots, asterisks (for pattern topics), and hyphens. Uppercase letters, spaces, and most special characters are rejected. The exception type is RuntimeException.","triggerScenarios":"Calling checkTopicWithErr() with exactly one topic that fails the regex — e.g. contains uppercase letters (MyTopic), spaces (my topic), underscores (my_topic), or special characters not in the allowed set.","commonSituations":"Topic name uses camelCase or uppercase; topic contains underscores (common in some naming conventions); trailing whitespace from config files; copy-paste from a URL-encoded topic name.","solutions":["Rename the topic to use only lowercase alphanumeric, colons, slashes, dots, asterisks, and hyphens.","If using Kafka, note that Kafka topics allow more characters but canal's MQUtil enforces a stricter subset.","Remove any whitespace, underscores, or uppercase letters from the topic name in canal.mq.topic."],"exampleFix":"// before (uppercase + underscore)\ncanal.mq.topic=Order_Events\n\n// after (lowercase, hyphen)\ncanal.mq.topic=order-events","handlingStrategy":"validation","validationCode":"// Pre-validate the topic against the allowed charset before calling checkTopicWithErr\nString topic = topics[0];\nif (topic == null || !topic.matches(\"^[0-9a-z:/.*-]+$\")) {\n    throw new IllegalArgumentException(\n        \"Topic '\" + topic + \"' contains invalid characters. \"\n        + \"Allowed: lowercase a-z, digits, ':', '/', '.', '*', '-'\");\n}\nMQUtil.checkTopicWithErr(topic);","typeGuard":"// Type guard for valid single-topic naming\npublic static boolean isValidTopicName(String topic) {\n    return topic != null && topic.matches(\"^[0-9a-z:/.*-]+$\");\n}","tryCatchPattern":"try {\n    MQUtil.checkTopicWithErr(topic);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"topic invalid:\")) {\n        logger.error(\"Topic name '{}' violates naming rules. Use lowercase alphanumeric, ':', '/', '.', '*', '-'.\");\n    }\n    throw e;\n}","preventionTips":["Use lowercase-only topic names with hyphens or dots as separators.","Avoid underscores, uppercase letters, and spaces in topic names.","Add a CI check that validates topic names against the allowed charset."],"tags":["mq","topic-validation","naming-convention","config-error"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}