apache/rocketmq · error · RemotingTooMuchRequestException

sendMessage call timeout

Error message

sendMessage call timeout

What it means

Thrown by MQClientAPIImpl.sendMessage in ASYNC mode as RemotingTooMuchRequestException: the elapsed time since the request began (beginStartTime, set when the whole send workflow started, including message encoding and any earlier attempts) already exceeds the full timeout budget, so the remaining budget for the actual network call is negative and the send is rejected before invoking.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java:577

        } else {
            if (sendSmartMsg || msg instanceof MessageBatch) {
                SendMessageRequestHeaderV2 requestHeaderV2 = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV2(requestHeader);
                request = RemotingCommand.createRequestCommand(msg instanceof MessageBatch ? RequestCode.SEND_BATCH_MESSAGE : RequestCode.SEND_MESSAGE_V2, requestHeaderV2);
            } else {
                request = RemotingCommand.createRequestCommand(RequestCode.SEND_MESSAGE, requestHeader);
            }
        }
        request.setBody(msg.getBody());

        switch (communicationMode) {
            case ONEWAY:
                this.remotingClient.invokeOneway(addr, request, timeoutMillis);
                return null;
            case ASYNC:
                final AtomicInteger times = new AtomicInteger();
                long costTimeAsync = System.currentTimeMillis() - beginStartTime;
                if (timeoutMillis < costTimeAsync) {
                    throw new RemotingTooMuchRequestException("sendMessage call timeout");
                }
                this.sendMessageAsync(addr, brokerName, msg, timeoutMillis - costTimeAsync, request, sendCallback, topicPublishInfo, instance,
                    retryTimesWhenSendFailed, times, context, producer);
                return null;
            case SYNC:
                long costTimeSync = System.currentTimeMillis() - beginStartTime;
                if (timeoutMillis < costTimeSync) {
                    throw new RemotingTooMuchRequestException("sendMessage call timeout");
                }
                return this.sendMessageSync(addr, brokerName, msg, timeoutMillis - costTimeSync, request);
            default:
                assert false;
                break;
        }

        return null;
    }

View on GitHub (pinned to 293f588571)

Solutions

  1. Increase producer.setSendMsgTimeout(timeoutMillis)
  2. Check the cause chain of earlier async failures — retries inherit the original deadline, so fix the root slowness (broker/network)
  3. Reduce message body size or move serialization off the send path
  4. Monitor client CPU: encoding and callback contention inflate costTime
  5. If it only appears on retries, cap retryTimesWhenSendFailed or accept the exception as budget exhaustion

Example fix

// before
producer.setSendMsgTimeout(500); // too small for large payloads
producer.send(msg, new SendCallback() {...});

// after
producer.setSendMsgTimeout(3000); // default, or higher for big messages
producer.send(msg, new SendCallback() {...});
Defensive patterns

Strategy: validation

Validate before calling

// ensure timeout budget exceeds known encode time before async send
long encodeBudgetMs = 500; // measured for your payload shape
if (producer.getSendMsgTimeout() <= encodeBudgetMs) {
    producer.setSendMsgTimeout(encodeBudgetMs + 2500);
}

Try / catch

producer.send(msg, new SendCallback() {
    public void onException(Throwable e) {
        if (e instanceof RemotingTooMuchRequestException) {
            // budget exhausted before invoke: raise sendMsgTimeout, do not blind-retry
        }
    }
    public void onSuccess(SendResult r) {}
});

Prevention

When it happens

Trigger: Async send where timeoutMillis is smaller than time already spent building/encoding the request — e.g. very small sendMsgTimeout, large message body serialization, or retry attempts (retry 2+) reusing beginStartTime so prior failures consumed the entire budget.

Common situations: Producer sendMsgTimeout lowered from the 3000ms default; large batched messages; async retry after a slow first attempt; overloaded client thread pool delaying execution until after the deadline; clock-sensitive latency budgets in canary/latency-testing tools.

Understand the failure class

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/157e59486a750b10. Report an issue: GitHub.