apache/rocketmq · error · AuthorizationException
topic list is empty.
Error message
topic list is empty.
What it means
Thrown by DefaultAuthorizationContextBuilder when building an authorization context for an UPDATE_AND_CREATE_TOPIC_LIST admin request whose decoded CreateTopicListRequestBody contains an empty (or null) topicConfigList. Before authorizing a CREATE action on each topic, the builder must derive one Resource per TopicConfig; an empty list leaves nothing to authorize, so the request is rejected with AuthorizationException instead of being silently allowed. This is a client-side payload validation failure, not a permission denial.
Source
Thrown at auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java:466
throw new AuthorizationException("lite subscription is null.");
}
addUniqueContext(result, liteSubscriptionResources, subject,
Resource.ofGroup(requireResource(subscription.getGroup(), "consumer group")),
Action.SUB, sourceIp);
addUniqueContext(result, liteSubscriptionResources, subject,
Resource.ofTopic(requireResource(subscription.getTopic(), "topic")),
Action.SUB, sourceIp);
}
break;
case RequestCode.UPDATE_BROKER_CONFIG:
result.add(DefaultAuthorizationContext.of(subject,
Resource.ofCluster(authConfig.getClusterName()), Action.UPDATE, sourceIp));
break;
case RequestCode.UPDATE_AND_CREATE_TOPIC_LIST:
CreateTopicListRequestBody topicListBody = decodeRequiredBody(
command, CreateTopicListRequestBody.class, "topic list");
if (CollectionUtils.isEmpty(topicListBody.getTopicConfigList())) {
throw new AuthorizationException("topic list is empty.");
}
Set<String> topicListResources = new LinkedHashSet<>();
for (TopicConfig topicConfig : topicListBody.getTopicConfigList()) {
if (topicConfig == null) {
throw new AuthorizationException("topic config is null.");
}
String topicName = requireResource(topicConfig.getTopicName(), "topic");
Resource resource = NamespaceUtil.isRetryTopic(topicName)
? Resource.ofGroup(topicName) : Resource.ofTopic(topicName);
addUniqueContext(result, topicListResources, subject, resource, Action.CREATE, sourceIp);
}
break;
case RequestCode.UPDATE_COLD_DATA_FLOW_CTR_CONFIG:
Properties properties = MixAll.string2Properties(
decodeRequiredText(command, "cold data flow config"));
if (properties == null || properties.isEmpty()) {
throw new AuthorizationException("cold data flow config is empty.");
}View on GitHub (pinned to 293f588571)
Solutions
- On the client, guard before sending: skip the updateTopicList call (or fail fast) when the topic config collection is empty.
- Verify the request body is a CreateTopicListRequestBody with a non-null 'topicConfigList' JSON key matching the broker's version.
- If the list is legitimately empty, treat it as a no-op locally instead of issuing the RPC.
- Check for null elements inside the list too — they trigger the sibling 'topic config is null.' error at the next check.
Example fix
// before
List<TopicConfig> configs = collectTopics();
adminBrokerExt.updateTopicList(configs); // throws when configs is empty
// after
List<TopicConfig> configs = collectTopics();
if (configs == null || configs.isEmpty()) {
return; // nothing to create, do not send the request
}
adminBrokerExt.updateTopicList(configs); Defensive patterns
Strategy: validation
Validate before calling
// before sending UPDATE_AND_CREATE_TOPIC_LIST
if (CollectionUtils.isEmpty(topicConfigList)) {
return; // or throw IllegalArgumentException("no topics to create");
}
requestBody.setTopicConfigList(topicConfigList); Try / catch
try { admin.updateTopicList(requestBody); }
catch (AuthorizationException e) {
if (e.getMessage().contains("topic list is empty")) { /* no-op, skip */ return; }
throw e;
} Prevention
- Guard bulk admin calls with an empty-collection short-circuit
- Log the list size before sending batch requests
- Unit-test the serialization of request bodies against the broker's schema
When it happens
Trigger: A client (e.g. AdminTool / mqadmin updateTopicList, or AdminBrokerProcessor path for RequestCode.UPDATE_AND_CREATE_TOPIC_LIST == 317) sends a CreateTopicListRequestBody whose serialized JSON has topicConfigList absent, null, or []. It can also fire if the body JSON deserializes but the field name is misspelled so the list stays null after decode.
Common situations: Scripts migrating topics in bulk that loop over an empty directory or glob; CI pipelines generating the topic list from a template that rendered zero entries; version drift between client and broker where an older client sends a different body schema so the list field never populates.
Related errors
- topic config is null.
- subscription group list is empty.
- The body of acl is null
- cold data flow config is empty.
- subscription group is null.
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/fc07e8e8167b0429.
Report an issue: GitHub.