apache / apache/rocketmq

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

Open Beginner friendly
#11,158 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
22.6k
Forks
12k
Avg merge
3d 1h
Merged PRs (30d)
27

Description

### Before Creating the Bug Report

- [x] I found a bug, not just asking a question, which should be created in [GitHub Discussions](https://github.com/apache/rocketmq/discussions).

- [x] I have searched the [GitHub Issues](https://github.com/apache/rocketmq/issues) and [GitHub Discussions](https://github.com/apache/rocketmq/discussions) of this repository and believe that this is not a duplicate.

- [x] 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%+`). 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_

Contributor guide

Open the contributing guide

Research direction

Start with TopicValidator.VALID_CHAR_BIT_MAP and the validation path that rejects the name generated by KeyBuilder.buildPopRetryTopicV2(). Reproduce with enableRetryTopicV2=true, then add coverage for a retry topic containing the `+` separator and verify that broker topic creation no longer returns INVALID_PARAMETER.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.