quarkusio/quarkus · error · RuntimeException

Found method annotated with the @AuthorizationPolicy annotat

Error message

Found method annotated with the @AuthorizationPolicy annotation that is not an endpoint: <class>#<method>

What it means

@AuthorizationPolicy placed on a method is only meaningful when that method is a JAX-RS/Quarkus REST endpoint that can be secured with the named policy. When the annotated method is not an endpoint, Quarkus cannot map the policy to any HTTP route and fails the build, reporting the class and method. Note that synthetic Kotlin suspend companion methods are skipped rather than rejected.

Source

Thrown at extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpSecurityProcessor.java:743

    @Record(ExecutionTime.STATIC_INIT)
    @BuildStep(onlyIf = AlwaysPropagateSecurityIdentity.class)
    IgnoredContextLocalDataKeysBuildItem dontPropagateSecurityIdentityToDuplicateContext(HttpSecurityRecorder recorder) {
        return new IgnoredContextLocalDataKeysBuildItem(recorder.getSecurityIdentityContextKeySupplier());
    }

    private static Stream<MethodInfo> getPolicyTargetEndpointCandidates(AnnotationTarget target,
            SecurityTransformer securityTransformer) {
        if (target.kind() == AnnotationTarget.Kind.METHOD) {
            var method = target.asMethod();
            if (!hasProperEndpointModifiers(method)) {
                if (method.isSynthetic() && method.name().endsWith(KOTLIN_SUSPEND_IMPL_SUFFIX)) {
                    // ATM there are 2 methods for Kotlin endpoint like this:
                    // @AuthorizationPolicy(name = "suspended")
                    // suspend fun sayHi() = "Hi"
                    // the synthetic method doesn't need to be secured, but it keeps security annotations
                    return Stream.empty();
                }
                throw new RuntimeException("""
                        Found method annotated with the @AuthorizationPolicy annotation that is not an endpoint: %s#%s
                        """.formatted(method.declaringClass().name().toString(), method.name()));
            }
            return Stream.of(method);
        }
        return target.asClass().methods().stream()
                .filter(HttpSecurityProcessor::hasProperEndpointModifiers)
                .filter(mi -> !securityTransformer.hasSecurityAnnotation(mi));
    }

    private static void validateAuthMechanismAnnotationUsage(Capabilities capabilities,
            VertxHttpBuildTimeConfig buildTimeConfig,
            DotName[] annotationNames) {
        if (buildTimeConfig.auth().proactive()
                || (capabilities.isMissing(Capability.RESTEASY_REACTIVE) && capabilities.isMissing(Capability.RESTEASY)
                        && capabilities.isMissing(Capability.WEBSOCKETS_NEXT))) {
            throw new ConfigurationException("Annotations '" + Arrays.toString(annotationNames) + "' can only be used when"
                    + " proactive authentication is disabled and either Quarkus REST, RESTEasy Classic or WebSockets Next"

View on GitHub (pinned to e1c734241f)

Solutions

  1. Move @AuthorizationPolicy to an actual JAX-RS resource method or to the resource class
  2. If it's a Kotlin suspend endpoint, ensure the annotation targets the endpoint method per the documented pattern
  3. Remove the annotation if the method is not an HTTP endpoint and secure it another way

Example fix

// before
@AuthorizationPolicy(name = "suspended")
public void helperMethod() { ... }
// after
@Path("/admin")
public class AdminResource {
    @GET
    @AuthorizationPolicy(name = "admin-policy")
    public String admin() { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Method m = targetMethod;
if (m.isAnnotationPresent(AuthorizationPolicy.class) &&
    !Arrays.stream(m.getAnnotations()).anyMatch(a -> a.annotationType().isAnnotationPresent(Path.class))) {
    throw new IllegalStateException("@AuthorizationPolicy only valid on JAX-RS endpoint methods");
}

Type guard

boolean isEndpointMethod(Method m) {
    return m.isAnnotationPresent(GET.class) || m.isAnnotationPresent(POST.class)
        || m.isAnnotationPresent(PUT.class) || m.isAnnotationPresent(DELETE.class);
}

Prevention

When it happens

Trigger: Placing @AuthorizationPolicy on a regular (non-endpoint) method — one not exposed via RESTEasy/Quarkus REST — or on a method the annotation scanner cannot resolve to an endpoint candidate.

Common situations: Annotating a service-layer method expecting security to apply; Kotlin endpoints where the real endpoint is the synthetic method; annotating a private/helper method by mistake.

Related errors


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