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

  1. On the client, guard before sending: skip the updateTopicList call (or fail fast) when the topic config collection is empty.
  2. Verify the request body is a CreateTopicListRequestBody with a non-null 'topicConfigList' JSON key matching the broker's version.
  3. If the list is legitimately empty, treat it as a no-op locally instead of issuing the RPC.
  4. 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

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


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