{"record":{"id":"7cd0651351aeed04","repo":"apache/rocketmq","slug":"subscription-group-is-null","errorCode":null,"errorMessage":"subscription group is null.","messagePattern":"subscription group is null\\.","errorType":"exception","errorClass":"AuthorizationException","httpStatus":null,"severity":"error","filePath":"auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java","lineNumber":502,"sourceCode":"                    }\n                    Set<String> coldDataResources = new LinkedHashSet<>();\n                    for (String consumerGroup : properties.stringPropertyNames()) {\n                        addUniqueContext(result, coldDataResources, subject,\n                            Resource.ofGroup(requireResource(consumerGroup, \"consumer group\")),\n                            Action.UPDATE, sourceIp);\n                    }\n                    break;\n                case RequestCode.REMOVE_COLD_DATA_FLOW_CTR_CONFIG:\n                    group = Resource.ofGroup(requireResource(\n                        decodeRequiredText(command, \"consumer group\"), \"consumer group\"));\n                    result.add(DefaultAuthorizationContext.of(subject, group, Action.UPDATE, sourceIp));\n                    break;\n                case RequestCode.UPDATE_AND_CREATE_SUBSCRIPTIONGROUP:\n                    SubscriptionGroupConfig subscriptionGroupConfig =\n                        RemotingSerializable.decode(command.getBody(), SubscriptionGroupConfig.class);\n                    if (subscriptionGroupConfig == null\n                        || StringUtils.isBlank(subscriptionGroupConfig.getGroupName())) {\n                        throw new AuthorizationException(\"subscription group is null.\");\n                    }\n                    result.add(DefaultAuthorizationContext.of(subject,\n                        Resource.ofGroup(subscriptionGroupConfig.getGroupName()), Action.CREATE, sourceIp));\n                    break;\n                case RequestCode.UPDATE_AND_CREATE_SUBSCRIPTIONGROUP_LIST:\n                    SubscriptionGroupList subscriptionGroupList = decodeRequiredBody(\n                        command, SubscriptionGroupList.class, \"subscription group list\");\n                    if (CollectionUtils.isEmpty(subscriptionGroupList.getGroupConfigList())) {\n                        throw new AuthorizationException(\"subscription group list is empty.\");\n                    }\n                    Set<String> subscriptionGroupResources = new LinkedHashSet<>();\n                    for (SubscriptionGroupConfig groupConfig : subscriptionGroupList.getGroupConfigList()) {\n                        if (groupConfig == null) {\n                            throw new AuthorizationException(\"subscription group config is null.\");\n                        }\n                        addUniqueContext(result, subscriptionGroupResources, subject,\n                            Resource.ofGroup(requireResource(groupConfig.getGroupName(), \"consumer group\")),\n                            Action.CREATE, sourceIp);","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java#L484-L520","documentation":"Thrown for UPDATE_AND_CREATE_SUBSCRIPTIONGROUP when the request body either fails to decode to a SubscriptionGroupConfig (decode returns null) or decodes but has a blank groupName. The group name is required to build the Resource.ofGroup(...) that the CREATE action is checked against, so without it the request is rejected before authorization proper.","triggerScenarios":"Calling mqadmin updateSubGroup / the broker admin API with a body whose JSON is not a SubscriptionGroupConfig, or one whose 'groupName' field is missing, empty, or whitespace. Note this path uses RemotingSerializable.decode directly (no decodeRequiredBody wrapper), so malformed JSON may instead surface as the generic 'parse authorization context error.' — a null decode or blank name is what reaches this exact message.","commonSituations":"Creating a subscription group with an empty name field in an ops UI; sending the wrong object type in the body after a client/broker version mismatch; groupName trimmed to empty by upstream templating.","solutions":["Set a non-blank groupName in the SubscriptionGroupConfig before serializing the body.","Verify the body JSON round-trips: RemotingSerializable.decode(bytes, SubscriptionGroupConfig.class) returns a config with a non-empty group name.","Use requireResource-style validation on the client whenever a group name comes from user input."],"exampleFix":"// before\nSubscriptionGroupConfig cfg = new SubscriptionGroupConfig();\ncfg.setGroupName(request.getGroup()); // may be null/blank\n\n// after\nString group = request.getGroup();\nif (StringUtils.isBlank(group)) { throw new IllegalArgumentException(\"group required\"); }\nSubscriptionGroupConfig cfg = new SubscriptionGroupConfig();\ncfg.setGroupName(group);","handlingStrategy":"validation","validationCode":"if (config == null || StringUtils.isBlank(config.getGroupName())) {\n    throw new IllegalArgumentException(\"subscription group name required\");\n}","typeGuard":null,"tryCatchPattern":"try { admin.createAndUpdateSubscriptionGroupConfig(config); }\ncatch (AuthorizationException e) {\n    if (\"subscription group is null.\".equals(e.getMessage())) { promptForGroupName(); return; }\n    throw e;\n}","preventionTips":["Require non-blank group names in admin UIs and scripts","Validate group names at input boundaries with the same isBlank rule"],"tags":["rocketmq","authorization","admin-api","consumer-group","null-safety"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}