alibaba/spring-cloud-alibaba · error · IllegalArgumentException
topic must not be empty
Error message
topic must not be empty
What it means
getAndWrapMessage throws IllegalArgumentException('topic must not be empty') if the resolved topic is null or blank. RocketMQ cannot address a message without a topic, so the binder refuses to construct the Message.
Source
Thrown at spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java:141
if (null == jsonObj) {
throw new RuntimeException(String.format(
"empty after conversion [messageConverter:%s,payloadClass:%s,payloadObj:%s]",
MESSAGE_CONVERTER.getClass(), payloadObj.getClass(),
payloadObj));
}
payloads = jsonObj.getBytes(charset);
}
}
catch (Exception e) {
throw new RuntimeException("convert to RocketMQ message failed.", e);
}
return getAndWrapMessage(topic, message.getHeaders(), payloads);
}
private static org.apache.rocketmq.common.message.Message getAndWrapMessage(
String topic, MessageHeaders headers, byte[] payloads) {
if (topic == null || topic.length() < 1) {
throw new IllegalArgumentException("topic must not be empty");
}
if (payloads == null || payloads.length < 1) {
throw new IllegalArgumentException("payload must not be empty");
}
org.apache.rocketmq.common.message.Message rocketMsg = new org.apache.rocketmq.common.message.Message(
topic, payloads);
if (Objects.nonNull(headers) && !headers.isEmpty()) {
Object tag = headers.getOrDefault(Headers.TAGS,
headers.get(toRocketHeaderKey(Headers.TAGS)));
if (!ObjectUtils.isEmpty(tag)) {
rocketMsg.setTags(String.valueOf(tag));
}
Object keys = headers.getOrDefault(Headers.KEYS,
headers.get(toRocketHeaderKey(Headers.KEYS)));
if (!ObjectUtils.isEmpty(keys)) {
rocketMsg.setKeys(keys.toString());
}View on GitHub (pinned to 115d590110)
Solutions
- Set `spring.cloud.stream.bindings.<output>.destination=<topic>`.
- Resolve any unresolved `${...}` placeholders in the destination.
- For programmatic sends, pass a non-blank topic.
Example fix
// before
spring:
cloud:
stream:
bindings:
out1:
destination: ${MISSING_TOPIC} # unresolved -> blank -> [137]
# after
spring:
cloud:
stream:
bindings:
out1:
destination: order-events Defensive patterns
Strategy: validation
Validate before calling
// Reject blank topics before conversion.
if (topic == null || topic.isBlank()) {
throw new IllegalArgumentException("RocketMQ topic is blank; set bindings.<output>.destination (avoids [137])");
} Prevention
- Always set a non-blank destination for outbound bindings.
- Provide defaults for placeholders to avoid blank resolution.
- Validate topic at startup for programmatic producers.
When it happens
Trigger: convertMessage2MQ is called with a null/empty topic - e.g. destination.getName() is blank, or a programmatic send omits the topic.
Common situations: Outbound binding destination not configured (blank `destination`); the destination resolved to empty due to a placeholder that was never substituted; a programmatic producer send with no topic.
Related errors
- Binding for channel {destination.getName()} has been disable
- TransactionMQProducer must have a TransactionListener !!!
- message hasn't been sent,cause by : the SendType must be in
- empty after conversion [messageConverter:%s,payloadClass:%s,
- group must be configured for DLQ{destination.getName()}
AI-assisted analysis of alibaba/spring-cloud-alibaba@115d590110 (2026-08-14).
Data as JSON: /api/errors/16966d192c5a2104.
Report an issue: GitHub.