apache/rocketmq · error · AuthorizationException

The decision is null or illegal.

Error message

The decision is null or illegal.

What it means

Thrown by AuthorizationMetadataManagerImpl.validate() when a PolicyEntry has a null decision. Every policy must explicitly state Decision.ALLOW or Decision.DENY so the evaluator can order and apply rules deterministically; there is no default decision.

Source

Thrown at auth/src/main/java/org/apache/rocketmq/auth/authorization/manager/AuthorizationMetadataManagerImpl.java:267

        if (CollectionUtils.isEmpty(entry.getActions())) {
            throw new AuthorizationException("The actions is empty.");
        }
        if (entry.getActions().contains(Action.ANY)) {
            throw new AuthorizationException("The actions can not be Any.");
        }
        Environment environment = entry.getEnvironment();
        if (environment != null && CollectionUtils.isNotEmpty(environment.getSourceIps())) {
            for (String sourceIp : environment.getSourceIps()) {
                if (StringUtils.isBlank(sourceIp)) {
                    throw new AuthorizationException("The source ip is empty.");
                }
                if (!IPAddressUtils.isValidIPOrCidr(sourceIp)) {
                    throw new AuthorizationException("The source ip is invalid.");
                }
            }
        }
        if (entry.getDecision() == null) {
            throw new AuthorizationException("The decision is null or illegal.");
        }
    }

    private <T> CompletableFuture<T> handleException(Exception e) {
        CompletableFuture<T> result = new CompletableFuture<>();
        Throwable throwable = ExceptionUtils.getRealException(e);
        result.completeExceptionally(throwable);
        return result;
    }

    private AuthenticationMetadataProvider getAuthenticationMetadataProvider() {
        if (authenticationMetadataProvider == null) {
            throw new IllegalStateException("The authenticationMetadataProvider is not configured.");
        }
        return authenticationMetadataProvider;
    }

    private AuthorizationMetadataProvider getAuthorizationMetadataProvider() {

View on GitHub (pinned to 293f588571)

Solutions

  1. Add "decision":"ALLOW" (or "DENY" as intended) to each policy in the ACL document
  2. In code, call entry.setDecision(Decision.ALLOW) before submitting the entry

Example fix

// before
{"resources":[{"type":"TOPIC","pattern":"order-*"}],"actions":["PUB","SUB"]}

// after
{"resources":[{"type":"TOPIC","pattern":"order-*"}],"actions":["PUB","SUB"],"decision":"ALLOW"}
Defensive patterns

Strategy: validation

Validate before calling

boolean policyComplete(PolicyEntry e) {
    return e.getResource() != null && e.getActions() != null && !e.getActions().isEmpty()
        && e.getDecision() != null;
}

Try / catch

try { metadataManager.updateAcl(acl).join(); }
catch (AuthorizationException e) { /* set missing decision and retry */ }

Prevention

When it happens

Trigger: createAcl/updateAcl with a policy JSON that omits the "decision" field, or programmatic construction of PolicyEntry without setDecision(...).

Common situations: ACL documents written by hand or generated by scripts that only fill resources and actions; schema drift where the decision field was renamed; mistaken assumption that omitting decision defaults to ALLOW.

Related errors


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