quarkusio/quarkus · error · IllegalStateException
WebSocket endpoint '%s' superclass '%s' is secured with the
Error message
WebSocket endpoint '%s' superclass '%s' is secured with the '%s' security annotation. Only the HTTP upgrade can be secured with this annotation. Please place the annotation on the endpoint class '%s' instead.
What it means
AuthorizationPolicy secures the HTTP upgrade request only, so the websockets-next processor requires it to be placed on the WebSocket endpoint class itself. If the annotation is found on a superclass of the endpoint, the build fails with guidance to move the annotation. This is a deliberate placement rule, not a bug.
Source
Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java:993
record PolicyToEndpoint(String policyName, String endpointId) {
}
return endpoints.stream()
.<PolicyToEndpoint> mapMulti((endpoint, consumer) -> {
var beanName = endpoint.beanClassName();
var beanClassInfo = index.getClassByName(beanName);
if (securityTransformer.hasSecurityAnnotation(beanClassInfo, AUTHORIZATION_POLICY)) {
var authorizationPolicyAnnotation = securityTransformer
.findFirstSecurityAnnotation(beanClassInfo, AUTHORIZATION_POLICY).get();
String policyName = authorizationPolicyAnnotation.value("name").asString();
consumer.accept(new PolicyToEndpoint(policyName, endpoint.id));
} else {
// we document that security annotations that secure the HTTP upgrade must be on the endpoint class
var superName = beanClassInfo.superName();
while (superName != null && !OBJECT.equals(superName)) {
var superClass = index.getClassByName(superName);
if (superClass != null
&& securityTransformer.hasSecurityAnnotation(superClass, AUTHORIZATION_POLICY)) {
throw new IllegalStateException("""
WebSocket endpoint '%s' superclass '%s' is secured with the '%s' security annotation.
Only the HTTP upgrade can be secured with this annotation.
Please place the annotation on the endpoint class '%s' instead.
""".formatted(endpoint.id, superClass.name(), AuthorizationPolicy.class.getName(),
beanName));
} else {
superName = superClass == null ? null : superClass.superName();
}
}
}
beanClassInfo.methods().forEach(mi -> {
if (securityTransformer.hasSecurityAnnotation(mi, AUTHORIZATION_POLICY)) {
throw new IllegalStateException("""
WebSocket endpoint '%s' has method '%s' secured with the '%s' security annotation.
Only the HTTP upgrade can be secured with this annotation.
Please place the annotation on the endpoint class instead.
""".formatted(beanName, mi.name(), AuthorizationPolicy.class.getName()));
}View on GitHub (pinned to e1c734241f)
Solutions
- Move @AuthorizationPolicy from the superclass onto each concrete WebSocket endpoint class.
- Remove the annotation from the shared base class and secure each endpoint individually.
- If shared behavior is needed, keep the base class annotation-free and apply the policy per endpoint.
- If you want one policy for many endpoints, consider securing the upgrade path via HTTP security policy configuration on the endpoint path instead.
Example fix
// before
@AuthorizationPolicy(name = "admin")
public abstract class BaseEndpoint { }
@WebSocket(path = "/ws")
public class MyEndpoint extends BaseEndpoint { }
// after
public abstract class BaseEndpoint { }
@WebSocket(path = "/ws")
@AuthorizationPolicy(name = "admin")
public class MyEndpoint extends BaseEndpoint { } Defensive patterns
Strategy: validation
Validate before calling
// Pre-check: AuthorizationPolicy must not sit on superclasses of a @WebSocket endpoint
Class<?> c = MyEndpoint.class;
while ((c = c.getSuperclass()) != null && c != Object.class) {
if (c.isAnnotationPresent(io.quarkus.security.AuthorizationPolicy.class))
throw new IllegalStateException("Move @AuthorizationPolicy from " + c + " to the endpoint class");
} Prevention
- Never place @AuthorizationPolicy on shared base classes of endpoints
- Document in team conventions that security annotations go on the endpoint class
- Review refactors that move security annotations into parent classes
- Search codebase for @AuthorizationPolicy before adding WebSocket endpoints
When it happens
Trigger: A @WebSocket endpoint class extends a base class annotated with @AuthorizationPolicy; during build the processor walks superName up to Object and throws on the first superclass carrying the annotation.
Common situations: Extracting a shared secured base class for multiple endpoints and assuming annotation inheritance works; refactoring security from endpoint classes into an abstract parent; copying HTTP-endpoint patterns (where class inheritance of security annotations is expected) into WebSocket endpoints.
Related errors
- WebSocket endpoint '%s' has method '%s' secured with the '%s
- Quarkus did not detect
- WebSocket endpoint '%s' requires secured HTTP upgrade but Qu
- @PermissionChecker annotation placed on the '%s' attribute '
- @PermissionChecker annotation instance placed on the '%s' re
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0bd4d60d69c612e0.
Report an issue: GitHub.