{"record":{"id":"b0a1fb95f49dadaa","repo":"apache/rocketmq","slug":"parse-authorization-context-error","errorCode":null,"errorMessage":"parse authorization context error.","messagePattern":"parse authorization context error\\.","errorType":"exception","errorClass":"AuthorizationException","httpStatus":null,"severity":"error","filePath":"auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java","lineNumber":615,"sourceCode":"                    for (String groupName : deleteGroupListRequestBody.getGroupNameList()) {\n                        group = Resource.ofGroup(requireResource(groupName, \"consumer group\"));\n                        addUniqueContext(result, deleteGroupResources, subject, group, Action.DELETE, sourceIp);\n                    }\n                    break;\n                default:\n                    result = buildContextByAnnotation(subject, command, sourceIp);\n                    break;\n            }\n            if (CollectionUtils.isNotEmpty(result)) {\n                result.forEach(r -> {\n                    r.setChannelId(context.channel().id().asLongText());\n                    r.setRpcCode(String.valueOf(command.getCode()));\n                });\n            }\n        } catch (AuthorizationException ex) {\n            throw ex;\n        } catch (Throwable t) {\n            throw new AuthorizationException(\"parse authorization context error.\", t);\n        }\n        return result;\n    }\n\n    private static <T> T decodeRequiredBody(RemotingCommand command, Class<T> bodyClass, String bodyName) {\n        if (command.getBody() == null || command.getBody().length == 0) {\n            throw new AuthorizationException(bodyName + \" is null.\");\n        }\n        T body = RemotingSerializable.decode(command.getBody(), bodyClass);\n        if (body == null) {\n            throw new AuthorizationException(bodyName + \" is null.\");\n        }\n        return body;\n    }\n\n    private static String decodeRequiredText(RemotingCommand command, String bodyName) {\n        if (command.getBody() == null || command.getBody().length == 0) {\n            throw new AuthorizationException(bodyName + \" is null.\");","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java#L597-L633","documentation":"This is the catch-all in DefaultAuthorizationContextBuilder#build: any Throwable raised while parsing the request into authorization contexts — other than an AuthorizationException, which is rethrown as-is — is wrapped in AuthorizationException('parse authorization context error.', t). Typical causes are JSON decode failures in RemotingSerializable.decode (wrong body class for the request code), ClassCastException in decodeCommandCustomHeader, protobuf/parameter errors in the gRPC paths, or NPEs in unlisted request-code branches. The root cause is in the attached cause, so always log t.getCause().","triggerScenarios":"Any request whose body/header cannot be parsed by the branch selected for its RequestCode: sending non-JSON bytes where a JSON body is expected, sending the wrong request code for the payload, malformed UTF-8, or a header class mismatch in decodeCommandCustomHeader. Since the default branch delegates to buildContextByAnnotation, annotation-driven codes with broken headers also land here.","commonSituations":"Client/broker version mismatch where the request-code-to-body mapping changed; hand-crafted RemotingCommand with an empty or binary body on an admin code; gzipped or encrypted bodies sent to codes the builder expects to decode plainly.","solutions":["Inspect the cause: catch and log ex.getCause() to identify the actual decode/parse failure.","Match request code to payload — send the body/header class the broker's builder expects for that RequestCode (check the switch cases in DefaultAuthorizationContextBuilder).","Align client and broker versions so request-code handling and body schemas agree.","If writing a custom request code, make sure the default annotation path can resolve its headers."],"exampleFix":"// before\ncatch (Exception e) { log.error(\"auth failed\", e.getMessage()); }\n\n// after\ncatch (AuthorizationException e) {\n    Throwable cause = e.getCause();\n    log.error(\"auth context parse failed, root:\", cause != null ? cause : e);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { authorizer.authorize(context); }\ncatch (AuthorizationException e) {\n    Throwable root = e.getCause() != null ? e.getCause() : e;\n    log.error(\"auth context parse failed; root cause:\", root); // decode errors hide here\n    throw e;\n}","preventionTips":["Always inspect getCause() of wrapped auth exceptions","Match body/header classes to request codes","Keep client and broker versions aligned","Test admin payloads against a staging broker before production"],"tags":["rocketmq","authorization","error-wrapping","deserialization","root-cause"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}