apache/rocketmq · error · MQClientException

16

16

Error message

topicPermission value: %s is invalid.

What it means

Thrown by Validators.checkTopicConfig when the TopicConfig's permission value fails PermName.isValid(). RocketMQ encodes topic permissions as a bitmask (2=READ, 4=WRITE, 6=READ|WRITE); any value outside the accepted set is rejected before the config is sent to the broker. The exception carries response code 16 (NO_PERMISSION). It exists to stop clients from pushing a malformed permission string to the server, which would silently produce an unusable topic.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/Validators.java:128

    }

    public static void isSystemTopic(String topic) throws MQClientException {
        if (TopicValidator.isSystemTopic(topic)) {
            throw new MQClientException(
                    String.format("The topic[%s] is conflict with system topic.", topic), null);
        }
    }

    public static void isNotAllowedSendTopic(String topic) throws MQClientException {
        if (TopicValidator.isNotAllowedSendTopic(topic)) {
            throw new MQClientException(
                    String.format("Sending message to topic[%s] is forbidden.", topic), null);
        }
    }

    public static void checkTopicConfig(final TopicConfig topicConfig) throws MQClientException {
        if (!PermName.isValid(topicConfig.getPerm())) {
            throw new MQClientException(ResponseCode.NO_PERMISSION,
                String.format("topicPermission value: %s is invalid.", topicConfig.getPerm()));
        }
    }

    public static void checkBrokerConfig(final Properties brokerConfig) throws MQClientException {
        String brokerPermission = brokerConfig.getProperty("brokerPermission");
        if (brokerPermission != null && !PermName.isValid(brokerPermission)) {
            throw new MQClientException(ResponseCode.NO_PERMISSION,
                    String.format("brokerPermission value: %s is invalid.", brokerPermission));
        }
    }
}

View on GitHub (pinned to 293f588571)

Solutions

  1. Set the perm to a valid bitmask: 6 (read+write), 4 (write-only), or 2 (read-only)
  2. If the perm comes from user input or a config file, parse and validate it with org.apache.rocketmq.common.protocol.body PermName.isValid(...) before constructing the TopicConfig
  3. Check for accidental double-setting of perm (e.g. setPerm(perm | 8) introducing an invalid bit)

Example fix

// before
topicConfig.setPerm(5); // invalid bitmask

// after
topicConfig.setPerm(PermName.PERM_READ | PermName.PERM_WRITE); // 6
Defensive patterns

Strategy: validation

Validate before calling

import org.apache.rocketmq.common.protocol.body.PermName;

boolean ok = PermName.isValid(String.valueOf(topicConfig.getPerm()));
if (!ok) {
    topicConfig.setPerm(PermName.PERM_READ | PermName.PERM_WRITE);
}

Try / catch

try {
    Validators.checkTopicConfig(topicConfig);
} catch (MQClientException e) {
    if (e.getResponseCode() == ResponseCode.NO_PERMISSION) {
        // fix perm value, log and surface config error to operator
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling an admin API that validates a TopicConfig (e.g. topic creation/update utilities that call Validators.checkTopicConfig) with topicConfig.setPerm() set to an invalid number such as 0, 5, 8, or a non-numeric string.

Common situations: Scripts or tools that build TopicConfig programmatically and pass an arbitrary int; porting code from another client where permissions were a string like 'rw'; typos when copying example configs.

Related errors


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