{"record":{"id":"a21e2f077f0362c7","repo":"apache/rocketmq","slug":"message-s-topic-not-equal-mq-s-topic","errorCode":null,"errorMessage":"message's topic not equal mq's topic","messagePattern":"message's topic not equal mq's topic","errorType":"validation","errorClass":"MQClientException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java","lineNumber":1235,"sourceCode":"        }\n    }\n\n    /**\n     * KERNEL SYNC -------------------------------------------------------\n     */\n    public SendResult send(Message msg, MessageQueue mq)\n        throws MQClientException, RemotingException, MQBrokerException, InterruptedException {\n        return send(msg, mq, this.defaultMQProducer.getSendMsgTimeout());\n    }\n\n    public SendResult send(Message msg, MessageQueue mq, long timeout)\n        throws MQClientException, RemotingException, MQBrokerException, InterruptedException {\n        long beginStartTime = System.currentTimeMillis();\n        this.makeSureStateOK();\n        Validators.checkMessage(msg, this.defaultMQProducer);\n\n        if (!msg.getTopic().equals(mq.getTopic())) {\n            throw new MQClientException(\"message's topic not equal mq's topic\", null);\n        }\n\n        long costTime = System.currentTimeMillis() - beginStartTime;\n        if (timeout < costTime) {\n            throw new RemotingTooMuchRequestException(\"call timeout\");\n        }\n\n        return this.sendKernelImpl(msg, mq, CommunicationMode.SYNC, null, null, timeout);\n    }\n\n    /**\n     * KERNEL ASYNC -------------------------------------------------------\n     */\n    public void send(Message msg, MessageQueue mq, SendCallback sendCallback)\n        throws MQClientException, RemotingException, InterruptedException {\n        send(msg, mq, sendCallback, this.defaultMQProducer.getSendMsgTimeout());\n    }\n","sourceCodeStart":1217,"sourceCodeEnd":1253,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java#L1217-L1253","documentation":"MQClientException thrown by send(Message, MessageQueue) variants when msg.getTopic() does not String.equals the target MessageQueue's topic. Sending to an explicit queue requires the message and queue to belong to the same topic - the client will not route a message of topic A into a queue of topic B. Checked after makeSureStateOK and Validators.checkMessage, before any timeout accounting or network call.","triggerScenarios":"triggerScenarios","commonSituations":"commonSituations","solutions":["Derive the queue and the message from the same topic constant: new Message(TOPIC, ...) and queues from fetchPublishMessageQueues(TOPIC)","If namespaces are in play, align both sides: build the message topic with the namespace, or strip it from both before comparing; log both values on failure","Add an assertion/utility before send: Objects.equals(msg.getTopic(), mq.getTopic()) with a clear error including both strings","Re-fetch queues when the producer's topic/namespace config changes instead of caching stale MessageQueue objects"],"exampleFix":"// before\nMessage msg = new Message(\"ORDER_TOPIC\", body);\nMessageQueue mq = userQueues.get(0); // queue of PAYMENT_TOPIC\nproducer.send(msg, mq);\n// after\nMessage msg = new Message(ORDER_TOPIC, body);\nList<MessageQueue> mqs = producer.fetchPublishMessageQueues(ORDER_TOPIC);\nproducer.send(msg, mqs.get(0));","handlingStrategy":"validation","validationCode":" public SendResult sendTo(Message msg, MessageQueue mq) throws Exception {\n    if (!Objects.equals(msg.getTopic(), mq.getTopic())) {\n        throw new IllegalArgumentException(\n            \"topic mismatch: message=\" + msg.getTopic() + \" queue=\" + mq.getTopic());\n    }\n    return producer.send(msg, mq);\n}","typeGuard":" boolean isQueueForTopic(MessageQueue mq, String topic) {\n    return mq != null && Objects.equals(mq.getTopic(), topic);\n}","tryCatchPattern":"try {\n    producer.send(msg, mq);\n} catch (MQClientException e) {\n    if (\"message's topic not equal mq's topic\".equals(e.getMessage())) {\n        throw new IllegalArgumentException(\"Queue \" + mq + \" not usable for topic \" + msg.getTopic(), e);\n    }\n    throw e;\n}","preventionTips":["Always pair message and queue with the same topic constant","Fetch queues via fetchPublishMessageQueues(topic) instead of constructing them by hand","Watch namespace handling: namespace the queue via queueWithNamespace or keep both sides bare","Add the Objects.equals guard in send utility methods for a clearer error message"],"tags":["rocketmq","producer","message-queue","topic-mismatch","validation"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}