{"record":{"id":"cb10c3471ab4c9bf","repo":"apache/rocketmq","slug":"unknown-resource-type","errorCode":null,"errorMessage":"unknown resource type.","messagePattern":"unknown resource type\\.","errorType":"exception","errorClass":"AuthorizationException","httpStatus":null,"severity":"error","filePath":"auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java","lineNumber":815,"sourceCode":"        apache.rocketmq.v2.Resource resource) {\n        return newSubContexts(metadata, ResourceType.GROUP, resource);\n    }\n\n    private static List<DefaultAuthorizationContext> newSubContexts(Metadata metadata, ResourceType resourceType,\n        apache.rocketmq.v2.Resource resource) {\n        if (resourceType == ResourceType.GROUP) {\n            if (resource == null || StringUtils.isBlank(resource.getName())) {\n                throw new AuthorizationException(\"group is null.\");\n            }\n            return newSubContexts(metadata, Resource.ofGroup(resource.getName()));\n        }\n        if (resourceType == ResourceType.TOPIC) {\n            if (resource == null || StringUtils.isBlank(resource.getName())) {\n                throw new AuthorizationException(\"topic is null.\");\n            }\n            return newSubContexts(metadata, Resource.ofTopic(resource.getName()));\n        }\n        throw new AuthorizationException(\"unknown resource type.\");\n    }\n\n    private static List<DefaultAuthorizationContext> newSubContexts(Metadata metadata, Resource resource) {\n        List<DefaultAuthorizationContext> result = new ArrayList<>();\n        Subject subject = null;\n        if (metadata.containsKey(GrpcConstants.AUTHORIZATION_AK)) {\n            subject = User.of(metadata.get(GrpcConstants.AUTHORIZATION_AK));\n        }\n        String sourceIp = StringUtils.substringBeforeLast(metadata.get(GrpcConstants.REMOTE_ADDRESS), CommonConstants.COLON);\n        result.add(DefaultAuthorizationContext.of(subject, resource, Action.SUB, sourceIp));\n        return result;\n    }\n}\n","sourceCodeStart":797,"sourceCodeEnd":829,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java#L797-L829","documentation":"DefaultAuthorizationContextBuilder.newSubContexts(Metadata, ResourceType, Resource) only knows how to build SUB contexts for GROUP and TOPIC resources. If the ResourceType of the incoming resource is anything else (or null), there is no code path to build an authorization context, so it throws to fail closed rather than authorize an unknown shape.","triggerScenarios":"A request reaches this builder with a ResourceType other than GROUP or TOPIC — e.g. a new ResourceType enum constant added by a newer server but handled by older auth code (version skew between broker/proxy modules), or a null ResourceType after a bad conversion from the protobuf layer.","commonSituations":"Mixed-version RocketMQ 5.x deployment (proxy newer than auth jar or vice versa); custom code that maps protobuf resources to the internal model and forgets to translate the type; future enum values (e.g. new resource kinds) reaching an older builder.","solutions":["Align versions: run proxy, broker, and auth modules from the same RocketMQ release (all 5.x.y identical).","If you maintain custom mapping code, ensure ResourceType is never null/unknown when converting apache.rocketmq.v2 resources to internal resources.","Check for a custom or shaded org.apache.rocketmq.auth builder on the classpath that predates the current enum; remove it.","Report upstream if a stock, same-version deployment reproduces it — the builder legitimately lacks a case for the new type."],"exampleFix":"// before (custom mapping drops the type)\nResource res = Resource.of(resourceProto.getName()); // resourceType left null\n\n// after\nResource res = Resource.of(\n    resourceProto.getName(),\n    ResourcePattern.LITERAL);\nres.setResourceType(mapType(resourceProto)); // never null for GROUP/TOPIC paths","handlingStrategy":"validation","validationCode":"// Guard before building auth contexts\nif (resourceType != ResourceType.GROUP && resourceType != ResourceType.TOPIC) {\n    throw new IllegalArgumentException(\n        \"Unsupported resource type for SUB context: \" + resourceType);\n}","typeGuard":"boolean isSubContextType(ResourceType t) {\n    return t == ResourceType.GROUP || t == ResourceType.TOPIC;\n}","tryCatchPattern":null,"preventionTips":["Keep broker, proxy, and auth modules on one RocketMQ release.","Assert resource types in custom proto->model conversion code.","Add an integration test per supported resource type through the auth chain."],"tags":["rocketmq","authorization","version-skew","validation"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}