apache/rocketmq · error · MQClientException
Topic or listener is null
Error message
Topic or listener is null
What it means
DefaultLitePullConsumerImpl.registerTopicMessageQueueChangeListener(topic, listener) throws MQClientException("Topic or listener is null") when either argument is null. The listener is invoked when the queue count of a topic changes (scale-up/scale-down), and the API stores it keyed by topic, so both are mandatory.
Source
Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultLitePullConsumerImpl.java:1270
return false;
}
for (MessageQueue messageQueue : set2) {
if (!set1.contains(messageQueue)) {
return false;
}
}
return true;
}
public AssignedMessageQueue getAssignedMessageQueue() {
return assignedMessageQueue;
}
public synchronized void registerTopicMessageQueueChangeListener(String topic,
TopicMessageQueueChangeListener listener) throws MQClientException {
if (topic == null || listener == null) {
throw new MQClientException("Topic or listener is null", null);
}
if (topicMessageQueueChangeListenerMap.containsKey(topic)) {
log.warn("Topic {} had been registered, new listener will overwrite the old one", topic);
}
topicMessageQueueChangeListenerMap.put(topic, listener);
if (this.serviceState == ServiceState.RUNNING) {
Set<MessageQueue> messageQueues = fetchMessageQueues(topic);
messageQueuesForTopic.put(topic, messageQueues);
}
}
private Set<MessageQueue> parseMessageQueues(Set<MessageQueue> queueSet) {
Set<MessageQueue> resultQueues = new HashSet<>();
for (MessageQueue messageQueue : queueSet) {
String userTopic = NamespaceUtil.withoutNamespace(messageQueue.getTopic(),
this.defaultLitePullConsumer.getNamespace());
resultQueues.add(new MessageQueue(userTopic, messageQueue.getBrokerName(), messageQueue.getQueueId()));
}View on GitHub (pinned to 293f588571)
Solutions
- Null-check both arguments and skip or fail registration with a clear message
- Provide a no-op listener implementation instead of null when you only need the side effects elsewhere
Example fix
// before
consumer.registerTopicMessageQueueChangeListener(topic, listenerOrNull);
// after
if (topic != null && listenerOrNull != null) {
consumer.registerTopicMessageQueueChangeListener(topic, listenerOrNull);
} Defensive patterns
Strategy: validation
Validate before calling
if (topic != null && listener != null) {
consumer.registerTopicMessageQueueChangeListener(topic, listener);
} Prevention
- Make the listener a required bean in DI wiring
- Register listeners in the same place topics are configured
When it happens
Trigger: registerTopicMessageQueueChangeListener(topic, null); passing a listener built conditionally that stayed null; registering before the topic string was resolved.
Common situations: Optional listeners wired via DI that were not configured; registering for a topic name that failed env substitution.
Related errors
- consumerGroup can not equal
- Topic can not be null or empty.
- Message queues can not be null or empty.
- subExpression can not be null or empty.
- Timeout must not be negative
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/f2fd197d8ebc49a4.
Report an issue: GitHub.