apache/rocketmq · error · AuthorizationException

topic config is null.

Error message

topic config is null.

What it means

Thrown while iterating the topicConfigList of an UPDATE_AND_CREATE_TOPIC_LIST request when an individual TopicConfig element is null. The builder dereferences each element (topicConfig.getTopicName()) to build a CREATE Resource, so a null slot in the list is rejected before any permission check runs. It is a payload-shape error: the list itself was non-empty but contains a null entry.

Source

Thrown at auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java:471

                        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.");
                    }
                    Set<String> coldDataResources = new LinkedHashSet<>();
                    for (String consumerGroup : properties.stringPropertyNames()) {
                        addUniqueContext(result, coldDataResources, subject,
                            Resource.ofGroup(requireResource(consumerGroup, "consumer group")),
                            Action.UPDATE, sourceIp);

View on GitHub (pinned to 293f588571)

Solutions

  1. Filter nulls out of the topic config list before serializing and sending the request.
  2. Fix the producer of the list so parse/build failures throw instead of yielding null elements.
  3. Log which index was null while building to find the bad source entry.

Example fix

// before
List<TopicConfig> list = topics.stream().map(this::parse).collect(toList());
body.setTopicConfigList(list); // may contain nulls

// after
List<TopicConfig> list = topics.stream().map(this::parse)
    .filter(Objects::nonNull).collect(toList());
if (list.isEmpty()) { return; }
body.setTopicConfigList(list);
Defensive patterns

Strategy: validation

Validate before calling

boolean valid = topicConfigList != null && !topicConfigList.isEmpty()
    && topicConfigList.stream().allMatch(Objects::nonNull);
if (!valid) { throw new IllegalArgumentException("topic config list has null entries"); }

Try / catch

try { admin.updateTopicList(body); }
catch (AuthorizationException e) {
    if ("topic config is null.".equals(e.getMessage())) { fixAndRetryWithoutNulls(); return; }
    throw e;
}

Prevention

When it happens

Trigger: A CreateTopicListRequestBody JSON like {"topicConfigList":[null,{"topicName":"t"}]} — e.g. a stream/mapping pipeline that inserts null for failed lookups, or a Java client doing new ArrayList<>(size) and setting only some indices, or Collections.nCopies(n, null).

Common situations: Bulk provisioning code that maps an input list to TopicConfig and leaves null on parse failure; JSON built by hand or by another language where trailing commas / missing entries decode to null; partial failures in a loop that adds null placeholders.

Related errors


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