apache/rocketmq · error · AuthorizationException

The body of acl is null

Error message

The body of acl is null

What it means

Create-ACL handler: the request body is JSON-decoded into AclInfo; if the body is absent/undecodable (decode returns null) or the policies list is empty, it throws AuthorizationException. The broker refuses to create an ACL with no policies.

Source

Thrown at broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java:3396

            .exceptionally(ex -> {
                LOGGER.error("list user by {} error", requestHeader.getFilter(), ex);
                return handleAuthException(response, ex);
            })
            .join();

        return response;
    }

    private RemotingCommand createAcl(ChannelHandlerContext ctx,
        RemotingCommand request) throws RemotingCommandException {
        RemotingCommand response = RemotingCommand.createResponseCommand(null);

        CreateAclRequestHeader requestHeader = request.decodeCommandCustomHeader(CreateAclRequestHeader.class);
        Subject subject = Subject.of(requestHeader.getSubject());

        AclInfo aclInfo = RemotingSerializable.decode(request.getBody(), AclInfo.class);
        if (aclInfo == null || CollectionUtils.isEmpty(aclInfo.getPolicies())) {
            throw new AuthorizationException("The body of acl is null");
        }

        Acl acl = AclConverter.convertAcl(aclInfo);
        if (acl != null && acl.getSubject() == null) {
            acl.setSubject(subject);
        }

        this.brokerController.getAuthorizationMetadataManager().createAcl(acl)
            .thenAccept(nil -> response.setCode(ResponseCode.SUCCESS))
            .exceptionally(ex -> {
                LOGGER.error("create acl for {} error", requestHeader.getSubject(), ex);
                return handleAuthException(response, ex);
            })
            .join();
        return response;
    }

    private RemotingCommand updateAcl(ChannelHandlerContext ctx,

View on GitHub (pinned to 293f588571)

Solutions

  1. Send a non-empty policies array in the request body, e.g. [{"effect":"ALLOW","actions":["PUB"],"resources":["topicA"]}].
  2. Verify the body is UTF-8 JSON of AclInfo and actually attached (ContentLength > 0) before sending.
  3. Check client-side model field names match the broker's AclInfo schema for your broker version.

Example fix

// before
CreateAclRequestHeader h = new CreateAclRequestHeader();
h.setSubject("User:alice");
request.setBody(null); // AuthorizationException

// after
String body = "{\"policies\":[{\"effect\":\"ALLOW\",\"actions\":[\"PUB\",\"SUB\"],\"resources\":[\"topicA\",\"groupB\"]}]}";
request.setBody(body.getBytes(StandardCharsets.UTF_8));
Defensive patterns

Strategy: validation

Validate before calling

AclInfo aclInfo = JSON.parseObject(body, AclInfo.class);
if (body == null || body.length == 0 || aclInfo == null
    || aclInfo.getPolicies() == null || aclInfo.getPolicies().isEmpty()) {
    throw new IllegalArgumentException("acl body must contain at least one policy");
}

Type guard

boolean isValidAclBody(byte[] body) {
    if (body == null || body.length == 0) return false;
    AclInfo info = JSON.parseObject(new String(body, StandardCharsets.UTF_8), AclInfo.class);
    return info != null && info.getPolicies() != null && !info.getPolicies().isEmpty();
}

Try / catch

catch (AuthorizationException e) { if (e.getMessage().contains("body of acl")) { fixRequestBodyAndResend(); } else throw e; }

Prevention

When it happens

Trigger: CreateAclRequest with null/empty body, body not valid AclInfo JSON, or an AclInfo whose 'policies' array is empty/null.

Common situations: Clients serializing AclInfo incorrectly (missing field name 'policies'); sending an ACL header-only request; proxies stripping the body; policy list filtered to empty client-side.

Related errors


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