{"record":{"id":"5232a15d10e55e72","repo":"apache/rocketmq","slug":"sending-message-to-topic-s-is-forbidden","errorCode":null,"errorMessage":"Sending message to topic[%s] is forbidden.","messagePattern":"Sending message to topic\\[(.+?)\\] is forbidden\\.","errorType":"validation","errorClass":"MQClientException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/org/apache/rocketmq/client/Validators.java","lineNumber":121,"sourceCode":"        }\n\n        if (isTopicOrGroupIllegal(topic)) {\n            throw new MQClientException(String.format(\n                    \"The specified topic[%s] contains illegal characters, allowing only %s\", topic,\n                    \"^[%|a-zA-Z0-9_-]+$\"), null);\n        }\n    }\n\n    public static void isSystemTopic(String topic) throws MQClientException {\n        if (TopicValidator.isSystemTopic(topic)) {\n            throw new MQClientException(\n                    String.format(\"The topic[%s] is conflict with system topic.\", topic), null);\n        }\n    }\n\n    public static void isNotAllowedSendTopic(String topic) throws MQClientException {\n        if (TopicValidator.isNotAllowedSendTopic(topic)) {\n            throw new MQClientException(\n                    String.format(\"Sending message to topic[%s] is forbidden.\", topic), null);\n        }\n    }\n\n    public static void checkTopicConfig(final TopicConfig topicConfig) throws MQClientException {\n        if (!PermName.isValid(topicConfig.getPerm())) {\n            throw new MQClientException(ResponseCode.NO_PERMISSION,\n                String.format(\"topicPermission value: %s is invalid.\", topicConfig.getPerm()));\n        }\n    }\n\n    public static void checkBrokerConfig(final Properties brokerConfig) throws MQClientException {\n        String brokerPermission = brokerConfig.getProperty(\"brokerPermission\");\n        if (brokerPermission != null && !PermName.isValid(brokerPermission)) {\n            throw new MQClientException(ResponseCode.NO_PERMISSION,\n                    String.format(\"brokerPermission value: %s is invalid.\", brokerPermission));\n        }\n    }","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/client/src/main/java/org/apache/rocketmq/client/Validators.java#L103-L139","documentation":"Validators.isNotAllowedSendTopic throws when the topic is on TopicValidator's forbidden-to-send list — %RETRY%* and %DLQ%* topics. Retry and DLQ topics are consumed, never published to directly; sending would corrupt retry semantics, so the client blocks it.","triggerScenarios":"producer.send(new Message(\"%DLQ%order-group\", ...)) or sending to '%RETRY%consumer-group'; checkMessage calls isNotAllowedSendTopic for every outbound message.","commonSituations":"Dead-letter handling reimplemented by writing to the DLQ topic manually; consumers that 'requeue' by producing into the retry topic; config that accidentally prefixes a business topic with %RETRY%.","solutions":["Send to your own business topic; to re-drive failures, resend the original message to its original topic.","Consume DLQ with a consumer subscribed to '%DLQ%group' instead of producing to it.","For delayed retry semantics, rely on the consumer's suspendCurrentQueueTimeMillis/retryTimesWhenConsumeFailed or schedule a delayed message to the original topic."],"exampleFix":"// before\nproducer.send(new Message(\"%DLQ%order-group\", tag, body)); // forbidden\n\n// after\nproducer.send(new Message(\"order-topic\", tag, body)); // resend to original topic","handlingStrategy":"validation","validationCode":"static boolean sendableTopic(String topic) {\n    return !org.apache.rocketmq.common.topic.TopicValidator.isNotAllowedSendTopic(topic);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never produce into %RETRY%/%DLQ% topics; consume DLQ via subscription instead.","For manual re-drive, resend the original payload to the original topic.","Add a send-wrapper guard that rejects retry/DLQ topics with a clear domain error."],"tags":["rocketmq","producer","dlq","retry","validation"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}