apache/rocketmq · error · IllegalArgumentException

Topic can not be null or empty.

Error message

Topic can not be null or empty.

What it means

IllegalArgumentException (wrapped in MQClientException("subscribe exception") by the enclosing catch) thrown by DefaultLitePullConsumerImpl.subscribe(topic, subExpression, listener) when topic is null or empty (StringUtils.isEmpty). It is a pure argument-validation failure raised before any subscription state changes.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultLitePullConsumerImpl.java:503

                final String topic = entry.getKey();
                this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic);
            }
        }
    }

    /**
     * subscribe data by customizing messageQueueListener
     *
     * @param topic
     * @param subExpression
     * @param messageQueueListener
     * @throws MQClientException
     */
    public synchronized void subscribe(String topic, String subExpression,
        MessageQueueListener messageQueueListener) throws MQClientException {
        try {
            if (StringUtils.isEmpty(topic)) {
                throw new IllegalArgumentException("Topic can not be null or empty.");
            }
            setSubscriptionType(SubscriptionType.SUBSCRIBE);
            SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(topic, subExpression);
            this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
            this.defaultLitePullConsumer.setMessageQueueListener(new MessageQueueListener() {
                @Override
                public void messageQueueChanged(String topic, Set<MessageQueue> mqAll, Set<MessageQueue> mqDivided) {
                    // First, update the assign queue
                    updateAssignQueueAndStartPullTask(topic, mqAll, mqDivided);
                    // run custom listener
                    messageQueueListener.messageQueueChanged(topic, mqAll, mqDivided);
                }
            });
            assignedMessageQueue.setRebalanceImpl(this.rebalanceImpl);
            if (serviceState == ServiceState.RUNNING) {
                this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
                updateTopicSubscribeInfoWhenSubscriptionChanged();
            }

View on GitHub (pinned to 293f588571)

Solutions

  1. Validate topics before subscribing: non-null and non-blank
  2. Filter blank entries out of dynamic topic lists
  3. Fix the config source supplying null/empty topic values
  4. Fail fast at app startup with a clear message listing which topic was invalid

Example fix

// before
for (String t : topicsStr.split(",")) {
    consumer.subscribe(t, "*"); // "" from trailing comma -> exception
}

// after
for (String t : topicsStr.split(",")) {
    String topic = t.trim();
    if (!topic.isEmpty()) {
        consumer.subscribe(topic, "*");
    }
}
Defensive patterns

Strategy: validation

Validate before calling

private void requireTopic(String t) {
    if (t == null || t.trim().isEmpty()) throw new IllegalArgumentException("topic required");
}
requireTopic(topic);
consumer.subscribe(topic, "*", listener);

Try / catch

try {
    consumer.subscribe(topic, "*", listener);
} catch (MQClientException e) {
    if (e.getCause() instanceof IllegalArgumentException) { /* bad topic: fix input */ }
    else throw e;
}

Prevention

When it happens

Trigger: Calling consumer.subscribe(topic, "*", listener) with topic = null, "" or whitespace-driven empty strings from config; dynamic topic lists containing blank entries from split("\n") on user input.

Common situations: Property-driven topics where the key is misspelled so the value resolves to null; parsing topic lists where trailing separators produce empty entries; NPE-adjacent bugs where a lookup returns null and is passed straight through.

Related errors


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