#11158·rocketmq

[Bug] TopicValidator rejects V2 retry topic names containing `+` separator introduced by KeyBuilder

Author: shihaomqCreated Sep 14, 2026Updated Sep 17, 2026

Before Creating the Bug Report

  • I found a bug, not just asking a question, which should be created in GitHub Discussions.

  • I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.

  • I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.

Runtime platform environment

  • RocketMQ version: 5.5.0 (also confirmed present in 5.5.1 and latest develop branch)
  • Component: broker (topic validation), common (KeyBuilder + TopicValidator)
  • Configuration: enableRetryTopicV2=true

RocketMQ version

RocketMQ version: 5.5.0

JDK Version

jdk11

Describe the Bug

When enableRetryTopicV2=true, KeyBuilder.buildPopRetryTopicV2() generates retry topic names using + as the separator (e.g., %RETRY%<group>+<topic>). However, TopicValidator.VALID_CHAR_BIT_MAP does not include + in its allowed character set [%|a-zA-Z0-9_-], causing the broker to reject these topic names with CODE: 29 (INVALID_PARAMETER) — "contains illegal characters".

Error log ERROR checkRetryTopicService - create topic on broker failed. topic:TopicConfig [topicName=%RETRY%GID_test+normal_topic, readQueueNums=1, writeQueueNums=1, perm=RW-, topicFilterType=SINGLE_TAG, topicSysFlag=0, order=false, attributes={}], broker:10.230.146.131:8080 org.apache.rocketmq.client.exception.MQClientException: CODE: 29 DESC: The specified topic: %RETRY%GID_test+normal_topic, contains illegal characters, allowing only ^[%|a-zA-Z0-9_-]+$ at org.apache.rocketmq.client.impl.MQClientAPIImpl.createTopic(MQClientAPIImpl.java:498) at org.apache.rocketmq.proxy.service.admin.DefaultAdminService.createTopicOnBroker(DefaultAdminService.java:119) at org.apache.rocketmq.proxy.service.admin.DefaultAdminService.createTopicOnTopicBrokerIfNotExist(DefaultAdminService.java:85) ...

Steps to Reproduce

  1. Set enableRetryTopicV2=true in broker config (or proxy config)
  2. Start a consumer that subscribes to a topic (this triggers CheckRetryTopicService to auto-create the V2 retry topic)
  3. Or send a retry message through the proxy (which rewrites the topic to V2 format via SendMessageActivity.handleRetryMessage())

What Did You Expect to See?

1

What Did You See Instead?

1

Additional Context

No response