apache/rocketmq · error · MQClientException

The specified topic is blank

Error message

The specified topic is blank

What it means

Validators.checkTopic rejects a topic that is null, empty, or whitespace-only. The check runs at the top of checkMessage and on subscribe/admin calls; without a topic the client cannot route the request, so it fails immediately with MQClientException (no code set).

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/Validators.java:97

        if (0 == msg.getBody().length) {
            throw new MQClientException(ResponseCode.MESSAGE_ILLEGAL, "the message body length is zero");
        }

        if (msg.getBody().length > defaultMQProducer.getMaxMessageSize()) {
            throw new MQClientException(ResponseCode.MESSAGE_ILLEGAL,
                "the message body size over max value, MAX: " + defaultMQProducer.getMaxMessageSize());
        }

        String lmqPath = msg.getUserProperty(MessageConst.PROPERTY_INNER_MULTI_DISPATCH);
        if (StringUtils.contains(lmqPath, File.separator)) {
            throw new MQClientException(ResponseCode.MESSAGE_ILLEGAL,
                "INNER_MULTI_DISPATCH " + lmqPath + " can not contains " + File.separator + " character");
        }
    }

    public static void checkTopic(String topic) throws MQClientException {
        if (UtilAll.isBlank(topic)) {
            throw new MQClientException("The specified topic is blank", null);
        }

        if (topic.length() > TOPIC_MAX_LENGTH) {
            throw new MQClientException(
                String.format("The specified topic is longer than topic max length %d.", TOPIC_MAX_LENGTH), null);
        }

        if (isTopicOrGroupIllegal(topic)) {
            throw new MQClientException(String.format(
                    "The specified topic[%s] contains illegal characters, allowing only %s", topic,
                    "^[%|a-zA-Z0-9_-]+$"), null);
        }
    }

    public static void isSystemTopic(String topic) throws MQClientException {
        if (TopicValidator.isSystemTopic(topic)) {
            throw new MQClientException(
                    String.format("The topic[%s] is conflict with system topic.", topic), null);

View on GitHub (pinned to 293f588571)

Solutions

  1. Pass a concrete topic name in the Message constructor / subscribe call.
  2. Fail fast on startup if the topic property is missing: Objects.requireNonNull(config.getTopic()).
  3. Centralize topic names as constants to avoid typos and unset variables.

Example fix

// before
producer.send(new Message(System.getenv("TOPIC"), tag, body)); // env var unset -> null

// after
String topic = Objects.requireNonNull(System.getenv("TOPIC"), "TOPIC env var must be set");
producer.send(new Message(topic, tag, body));
Defensive patterns

Strategy: validation

Validate before calling

static String requireTopic(String topic) {
    if (topic == null || topic.isBlank()) {
        throw new IllegalArgumentException("topic must be non-blank");
    }
    return topic;
}

Prevention

When it happens

Trigger: new Message(null/"", body); consumer.subscribe("", "*"); topic read from config that resolved blank; topic variable from a map.get() returning null.

Common situations: Missing 'rocketmq.producer.topic' property in Spring config; dynamic topic resolution failing silently to empty; refactoring constants and the topic constant left unset.

Related errors


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