{"record":{"id":"d0541603b873fdab","repo":"quarkusio/quarkus","slug":"the-s-policies-required-by-the-s-annotation","errorCode":null,"errorMessage":"The '%s' policies required by the '%s' annotation instances are missing: %s","messagePattern":"The '(.+?)' policies required by the '(.+?)' annotation instances are missing: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketServerRecorder.java","lineNumber":262,"sourceCode":"\n                    endpointToPolicy = new HashMap<>();\n                    Instance<HttpSecurityPolicy> policies = ctx.getInjectedReference(new TypeLiteral<>() {\n                    });\n                    var policyNameToEndpointsRemainder = new HashMap<>(policyNameToEndpoints);\n                    for (HttpSecurityPolicy policy : policies) {\n                        String policyName = policy.name();\n                        if (policyName != null && policyNameToEndpoints.containsKey(policyName)) {\n                            for (String endpoint : policyNameToEndpoints.get(policyName)) {\n                                endpointToPolicy.put(endpoint, policy);\n                            }\n                            policyNameToEndpointsRemainder.remove(policyName);\n                        }\n                    }\n                    if (!policyNameToEndpointsRemainder.isEmpty()) {\n                        String missingPolicies = policyNameToEndpointsRemainder.entrySet().stream()\n                                .map(e -> \"policy '%s' is required by endpoints '%s'\".formatted(e.getKey(), e.getValue()))\n                                .collect(Collectors.joining(System.lineSeparator()));\n                        throw new RuntimeException(\"The '%s' policies required by the '%s' annotation instances are missing: %s\"\n                                .formatted(HttpSecurityPolicy.class.getName(), AuthorizationPolicy.class.getName(),\n                                        missingPolicies));\n                    }\n                }\n                return new SecurityHttpUpgradeCheck(config.security().authFailureRedirectUrl().orElse(null), endpointToCheck,\n                        securityEventHelper, endpointToPolicy, authorizationRequestContext);\n            }\n        };\n    }\n\n    public Function<SyntheticCreationalContext<HttpUpgradeSecurityInterceptor>, HttpUpgradeSecurityInterceptor> createHttpUpgradeSecurityInterceptor(\n            Map<String, String> classNameToEndpointId) {\n        return new Function<SyntheticCreationalContext<HttpUpgradeSecurityInterceptor>, HttpUpgradeSecurityInterceptor>() {\n            @Override\n            public HttpUpgradeSecurityInterceptor apply(SyntheticCreationalContext<HttpUpgradeSecurityInterceptor> ctx) {\n                EagerSecurityInterceptorStorage storage = ctx.getInjectedReference(EagerSecurityInterceptorStorage.class);\n                Map<String, Consumer<RoutingContext>> endpointIdToInterceptor = new HashMap<>();\n                classNameToEndpointId.forEach((className, endpointId) -> {","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketServerRecorder.java#L244-L280","documentation":"At build/recorder time, the websockets-next server collects HttpSecurityPolicy instances required by @AuthorizationPolicy-annotated endpoints. If any required named policy is not registered as an HttpSecurityPolicy bean, the recorder throws this RuntimeException listing the missing policies and the endpoints that require them.","triggerScenarios":"An endpoint method or class annotated with @AuthorizationPolicy(value=\"policy-name\") (or similar instance) whose named policy has no corresponding HttpSecurityPolicy CDI bean registered — or the bean was removed/renamed.","commonSituations":"Renaming an HttpSecurityPolicy bean name without updating @AuthorizationPolicy; forgetting to register a custom policy class as a @Bean; removing a security extension that provided the policy.","solutions":["Implement and register an HttpSecurityPolicy CDI bean with the exact required name","Verify the name in @AuthorizationPolicy matches the policy's name()","Check that the extension providing the policy (e.g. quarkus-oidc, quarkus-http-security) is a dependency","Review the error message: it lists each missing policy and its dependent endpoints"],"exampleFix":"// before\n@AuthorizationPolicy(name = \"admin-only\") // no policy registered\n// after\n@Singleton\npublic class AdminOnlyPolicy implements HttpSecurityPolicy {\n    public String name() { return \"admin-only\"; }\n    ...\n}","handlingStrategy":"validation","validationCode":"// startup smoke: ensure every @AuthorizationPolicy name has an HttpSecurityPolicy bean\nSet<String> required = Set.of(\"admin-only\");\nrequired.forEach(name -> {\n    if (instance.list(HttpSecurityPolicy.class).stream().noneMatch(p -> name.equals(p.name())))\n        throw new IllegalStateException(\"Missing policy: \" + name);\n});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep @AuthorizationPolicy names and HttpSecurityPolicy.name() in one constants class","Add an ArC/startup test asserting all referenced policies resolve","Verify required security extensions are on the classpath"],"tags":["websockets","security","authorization","build-time"],"backgroundTag":"missing-security-policy","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}