{"record":{"id":"817d054656b4532f","repo":"apache/rocketmq","slug":"the-body-of-acl-is-null","errorCode":null,"errorMessage":"The body of acl is null","messagePattern":"The body of acl is null","errorType":"exception","errorClass":"AuthorizationException","httpStatus":null,"severity":"error","filePath":"broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java","lineNumber":3396,"sourceCode":"            .exceptionally(ex -> {\n                LOGGER.error(\"list user by {} error\", requestHeader.getFilter(), ex);\n                return handleAuthException(response, ex);\n            })\n            .join();\n\n        return response;\n    }\n\n    private RemotingCommand createAcl(ChannelHandlerContext ctx,\n        RemotingCommand request) throws RemotingCommandException {\n        RemotingCommand response = RemotingCommand.createResponseCommand(null);\n\n        CreateAclRequestHeader requestHeader = request.decodeCommandCustomHeader(CreateAclRequestHeader.class);\n        Subject subject = Subject.of(requestHeader.getSubject());\n\n        AclInfo aclInfo = RemotingSerializable.decode(request.getBody(), AclInfo.class);\n        if (aclInfo == null || CollectionUtils.isEmpty(aclInfo.getPolicies())) {\n            throw new AuthorizationException(\"The body of acl is null\");\n        }\n\n        Acl acl = AclConverter.convertAcl(aclInfo);\n        if (acl != null && acl.getSubject() == null) {\n            acl.setSubject(subject);\n        }\n\n        this.brokerController.getAuthorizationMetadataManager().createAcl(acl)\n            .thenAccept(nil -> response.setCode(ResponseCode.SUCCESS))\n            .exceptionally(ex -> {\n                LOGGER.error(\"create acl for {} error\", requestHeader.getSubject(), ex);\n                return handleAuthException(response, ex);\n            })\n            .join();\n        return response;\n    }\n\n    private RemotingCommand updateAcl(ChannelHandlerContext ctx,","sourceCodeStart":3378,"sourceCodeEnd":3414,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#L3378-L3414","documentation":"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.","triggerScenarios":"CreateAclRequest with null/empty body, body not valid AclInfo JSON, or an AclInfo whose 'policies' array is empty/null.","commonSituations":"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.","solutions":["Send a non-empty policies array in the request body, e.g. [{\"effect\":\"ALLOW\",\"actions\":[\"PUB\"],\"resources\":[\"topicA\"]}].","Verify the body is UTF-8 JSON of AclInfo and actually attached (ContentLength > 0) before sending.","Check client-side model field names match the broker's AclInfo schema for your broker version."],"exampleFix":"// before\nCreateAclRequestHeader h = new CreateAclRequestHeader();\nh.setSubject(\"User:alice\");\nrequest.setBody(null); // AuthorizationException\n\n// after\nString body = \"{\\\"policies\\\":[{\\\"effect\\\":\\\"ALLOW\\\",\\\"actions\\\":[\\\"PUB\\\",\\\"SUB\\\"],\\\"resources\\\":[\\\"topicA\\\",\\\"groupB\\\"]}]}\";\nrequest.setBody(body.getBytes(StandardCharsets.UTF_8));","handlingStrategy":"validation","validationCode":"AclInfo aclInfo = JSON.parseObject(body, AclInfo.class);\nif (body == null || body.length == 0 || aclInfo == null\n    || aclInfo.getPolicies() == null || aclInfo.getPolicies().isEmpty()) {\n    throw new IllegalArgumentException(\"acl body must contain at least one policy\");\n}","typeGuard":"boolean isValidAclBody(byte[] body) {\n    if (body == null || body.length == 0) return false;\n    AclInfo info = JSON.parseObject(new String(body, StandardCharsets.UTF_8), AclInfo.class);\n    return info != null && info.getPolicies() != null && !info.getPolicies().isEmpty();\n}","tryCatchPattern":"catch (AuthorizationException e) { if (e.getMessage().contains(\"body of acl\")) { fixRequestBodyAndResend(); } else throw e; }","preventionTips":["Always attach a non-empty policies array in ACL create/update bodies.","Validate the serialized JSON client-side before sending."],"tags":["rocketmq","broker","acl","authorization","validation","admin-api"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}