apache/rocketmq · error · MQClientException

The topic[%s] is conflict with system topic.

Error message

The topic[%s] is conflict with system topic.

What it means

Validators.isSystemTopic throws when the topic matches a reserved system topic (per TopicValidator.isSystemTopic): TBW102, benchmark_topic*, OFFSET_MOVED_TIME_TABLE, SCHEDULE_TOPIC_XXXX, %RETRY%..., %DLQ%..., rmq_sys_*, and similar. User operations on these names are blocked to prevent corrupting broker internals.

Source

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

        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);
        }
    }

    public static void isNotAllowedSendTopic(String topic) throws MQClientException {
        if (TopicValidator.isNotAllowedSendTopic(topic)) {
            throw new MQClientException(
                    String.format("Sending message to topic[%s] is forbidden.", topic), null);
        }
    }

    public static void checkTopicConfig(final TopicConfig topicConfig) throws MQClientException {
        if (!PermName.isValid(topicConfig.getPerm())) {
            throw new MQClientException(ResponseCode.NO_PERMISSION,
                String.format("topicPermission value: %s is invalid.", topicConfig.getPerm()));
        }
    }

View on GitHub (pinned to 293f588571)

Solutions

  1. Rename the user topic so it does not match system patterns (avoid prefixes %RETRY%, %DLQ%, rmq_sys_, and the fixed names like TBW102).
  2. Filter system topics out of admin scripts via TopicValidator.isSystemTopic before operating.
  3. Reserve a naming prefix (e.g. 'app-') for user topics by convention.

Example fix

// before
adminTopic "%RETRY%audit-group" // collides with retry system topic

// after
adminTopic "app-audit-retry-view" // ordinary user topic
Defensive patterns

Strategy: validation

Validate before calling

static boolean isUserTopic(String topic) {
    return !org.apache.rocketmq.common.topic.TopicValidator.isSystemTopic(topic);
}

Prevention

When it happens

Trigger: Sending to or creating a topic named like a system topic, e.g. producer.send to '%RETRY%mygroup' or mqadmin updateTopic -t SCHEDULE_TOPIC_XXXX; also validations in DefaultMQAdminExt topic creation.

Common situations: Choosing a business topic name that collides with rmq_sys_* or starts with %RETRY%/%DLQ%; tooling scripts that enumerate and recreate all topics including system ones.

Related errors


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