quarkusio/quarkus · error · IllegalStateException

WebSocket endpoint '%s' has method '%s' secured with the '%s

Error message

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.

What it means

AuthorizationPolicy secures only the HTTP upgrade, so it must be placed on the endpoint class — never on individual endpoint methods. The processor scans all methods of each endpoint class during build and fails if any carries the annotation.

Source

Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java:1006

                        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()));
                        }
                    });
                })
                .collect(groupingBy(PolicyToEndpoint::policyName, mapping(PolicyToEndpoint::endpointId, toSet())));
    }

    static String mergePath(String prefix, String path) {
        if (prefix.endsWith("/")) {
            prefix = prefix.substring(0, prefix.length() - 1);
        }
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        return prefix + path;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove @AuthorizationPolicy from the method and place it on the endpoint class instead.
  2. Secure per-connection authorization inside the callback using SecurityIdentity / WebSocketSecurity APIs if per-operation checks are truly needed.
  3. Review all endpoint methods for stray security annotations copied from REST resources.
  4. Use the endpoint-class-level policy or HTTP upgrade security policy for coarse-grained control.

Example fix

// before
@WebSocket(path = "/ws")
public class MyEndpoint {
    @OnMessage
    @AuthorizationPolicy(name = "admin")
    void onMessage(String msg) { }
}

// after
@WebSocket(path = "/ws")
@AuthorizationPolicy(name = "admin")
public class MyEndpoint {
    @OnMessage
    void onMessage(String msg) { }
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: no endpoint method may carry @AuthorizationPolicy
for (Method m : MyEndpoint.class.getDeclaredMethods()) {
    if (m.isAnnotationPresent(io.quarkus.security.AuthorizationPolicy.class))
        throw new IllegalStateException("@AuthorizationPolicy belongs on the endpoint class, not " + m);
}

Prevention

When it happens

Trigger: A method of a @WebSocket endpoint class (e.g. an @OnMessage/@OnOpen callback) is annotated with @AuthorizationPolicy; the build-time check securityTransformer.hasSecurityAnnotation(mi, AUTHORIZATION_POLICY) matches and throws.

Common situations: Trying to secure individual message handlers as one would secure JAX-RS resource methods; auto-import/auto-complete adding the annotation at method level; applying copy-pasted security annotations from REST endpoints to WebSocket callbacks.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/69f8738e2965a2af. Report an issue: GitHub.