apache/rocketmq · error · RemotingTooMuchRequestException
sendKernelImpl call timeout
Error message
sendKernelImpl call timeout
What it means
RemotingTooMuchRequestException thrown in sendKernelImpl's ASYNC branch: before delegating to sendMessage, the client computes costTimeAsync = now - beginStartTime (which starts back in sendDefaultImpl/send with callback, covering route lookup, selector, and per-attempt overhead) and if it already meets/exceeds the total timeout, it aborts instead of issuing the RPC with a non-positive remaining timeout. Pure client-side deadline check on the async path.
Source
Thrown at client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java:1045
//If msg body was compressed, msgbody should be reset using prevBody.
//Clone new message using compressed message body and recover origin massage.
//Fix bug:https://github.com/apache/rocketmq-externals/issues/66
tmpMessage = MessageAccessor.cloneMessage(msg);
messageCloned = true;
msg.setBody(prevBody);
}
if (topicWithNamespace) {
if (!messageCloned) {
tmpMessage = MessageAccessor.cloneMessage(msg);
messageCloned = true;
}
msg.setTopic(NamespaceUtil.withoutNamespace(msg.getTopic(), this.defaultMQProducer.getNamespace()));
}
long costTimeAsync = System.currentTimeMillis() - beginStartTime;
if (timeout < costTimeAsync) {
throw new RemotingTooMuchRequestException("sendKernelImpl call timeout");
}
sendResult = this.mQClientFactory.getMQClientAPIImpl().sendMessage(
brokerAddr,
brokerName,
tmpMessage,
requestHeader,
timeout - costTimeAsync,
communicationMode,
sendCallback,
topicPublishInfo,
this.mQClientFactory,
this.defaultMQProducer.getRetryTimesWhenSendAsyncFailed(),
context,
this);
break;
case ONEWAY:
case SYNC:
long costTimeSync = System.currentTimeMillis() - beginStartTime;View on GitHub (pinned to 293f588571)
Solutions
- Increase async send timeout (setSendMsgTimeout or the per-call timeout) so retries fit inside the budget
- Warm route caches at startup (fetchPublishMessageQueues for hot topics) to remove first-send lookup cost
- Reduce retryTimesWhenSendAsyncFailed or set sendMsgTimeout accounting for (retries+1)*worst-case attempt time
- Handle RemotingTooMuchRequestException in the SendCallback by falling back to local queueing/dead-letter rather than dropping
Example fix
// before producer.setSendMsgTimeout(300); producer.send(msg, callback); // retries consume budget -> timeout // after producer.setSendMsgTimeout(3_000); producer.setRetryTimesWhenSendAsyncFailed(1); producer.send(msg, callback);
Defensive patterns
Strategy: retry
Validate before calling
producer.setSendMsgTimeout(Math.max(producer.getSendMsgTimeout(),
(producer.getRetryTimesWhenSendAsyncFailed() + 1) * expectedRttMs * 2));
producer.fetchPublishMessageQueues(topic); // warm route cache Try / catch
producer.send(msg, new SendCallback() {
public void onSuccess(SendResult r) { ack(); }
public void onException(Throwable e) {
if (e instanceof RemotingTooMuchRequestException) spoolAndRetryLater(msg); // deadline, not broker rejection
else log.error("send failed", e);
}
}); Prevention
- Warm route caches before serving traffic
- Budget async timeout for (asyncRetries+1) attempts
- In SendCallback, distinguish RemotingTooMuchRequestException from broker errors - deadline expiry deserves spool/backoff, not immediate retry
- Load-test async throughput to size executor and timeout together
When it happens
Trigger: triggerScenarios
Common situations: commonSituations
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- sendMessage call timeout
- sendSelectImpl call timeout
- sendDefaultImpl call timeout
- call timeout
- Topic of the message does not match its target message queue
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/03deece932a02e58.
Report an issue: GitHub.