{"record":{"id":"ef5650d2568ffef9","repo":"apache/rocketmq","slug":"select-message-queue-threw-exception","errorCode":null,"errorMessage":"select message queue threw exception.","messagePattern":"select message queue threw exception\\.","errorType":"exception","errorClass":"MQClientException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java","lineNumber":702,"sourceCode":"    public MessageQueue invokeMessageQueueSelector(Message msg, MessageQueueSelector selector, Object arg,\n                                                   final long timeout) throws MQClientException, RemotingTooMuchRequestException {\n        long beginStartTime = System.currentTimeMillis();\n        this.makeSureStateOK();\n        Validators.checkMessage(msg, this.defaultMQProducer);\n\n        TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());\n        if (topicPublishInfo != null && topicPublishInfo.ok()) {\n            MessageQueue mq = null;\n            try {\n                List<MessageQueue> messageQueueList =\n                        mQClientFactory.getMQAdminImpl().parsePublishMessageQueues(topicPublishInfo.getMessageQueueList());\n                Message userMessage = MessageAccessor.cloneMessage(msg);\n                String userTopic = NamespaceUtil.withoutNamespace(userMessage.getTopic(), mQClientFactory.getClientConfig().getNamespace());\n                userMessage.setTopic(userTopic);\n\n                mq = mQClientFactory.getClientConfig().queueWithNamespace(selector.select(messageQueueList, userMessage, arg));\n            } catch (Throwable e) {\n                throw new MQClientException(\"select message queue threw exception.\", e);\n            }\n\n            long costTime = System.currentTimeMillis() - beginStartTime;\n            if (timeout < costTime) {\n                throw new RemotingTooMuchRequestException(\"sendSelectImpl call timeout\");\n            }\n            if (mq != null) {\n                return mq;\n            } else {\n                throw new MQClientException(\"select message queue return null.\", null);\n            }\n        }\n\n        validateNameServerSetting();\n        throw new MQClientException(\"No route info for this topic, \" + msg.getTopic(), null);\n    }\n\n    public MessageQueue selectOneMessageQueue(final TopicPublishInfo tpInfo, final String lastBrokerName, final boolean resetIndex) {","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java#L684-L720","documentation":"MQClientException thrown from invokeMessageQueueSelector when user-supplied MessageQueueSelector.select(...) (or the queue parsing / namespace handling around it) throws any Throwable. The client catches Throwable deliberately so a broken selector never silently skips selection, wraps the original exception as the cause, and aborts the send-select call. The stack trace of the cause contains the real error in your selector code.","triggerScenarios":"triggerScenarios","commonSituations":"commonSituations","solutions":["Read the wrapped cause in the MQClientException - it names the exact line in your selector that threw","Make the selector defensive: null/size checks on mqs, validate arg type before casting, bound the hash result with Math.floorMod(..., mqs.size())","Log arg + queue list inside select() during development to catch contract mismatches","Add a unit test invoking the selector with the same arg types and a 1-queue list, the minimal failure case"],"exampleFix":"// before\nMessageQueueSelector s = (mqs, m, arg) -> mqs.get((Integer) arg); // ClassCastException/NPE risk\n// after\nMessageQueueSelector s = (mqs, m, arg) -> {\n    if (mqs == null || mqs.isEmpty() || arg == null) return null;\n    int i = Math.floorMod(((Number) arg).intValue(), mqs.size());\n    return mqs.get(i);\n};","handlingStrategy":"try-catch","validationCode":" // exercise selector logic before wiring it in\nList<MessageQueue> mqs = producer.fetchPublishMessageQueues(topic);\nMessageQueue mq = selector.select(mqs, sampleMessage, sampleArg);\nObjects.requireNonNull(mq, \"selector must return a queue\");","typeGuard":" MessageQueueSelector safeSelector = (mqs, m, arg) -> {\n    if (mqs == null || mqs.isEmpty() || arg == null) {\n        throw new IllegalArgumentException(\"bad selector input\");\n    }\n    return mqs.get(Math.floorMod(((Number) arg).intValue(), mqs.size()));\n};","tryCatchPattern":"try {\n    producer.send(msg, selector, arg);\n} catch (MQClientException e) {\n    if (\"select message queue threw exception.\".equals(e.getMessage()) && e.getCause() != null) {\n        log.error(\"Selector bug\", e.getCause()); // real stack trace is in the cause\n    }\n    throw e;\n}","preventionTips":["Never index mqs without bounds-checking; use Math.floorMod","Validate/cast arg inside select before using it","Unit-test selectors with empty list, null arg, and min/max queue counts","Keep selectors pure and fast - no I/O, no external lookups"],"tags":["rocketmq","producer","message-queue-selector","user-code"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}