quarkusio/quarkus · error · RuntimeException
Unable to determine if the '${unsecuredMethod}' method shoul
Error message
Unable to determine if the '${unsecuredMethod}' method should inherit security annotation of the '${securedMethod}' method (generics not supported yet) What it means
When a class implements an interface whose method carries a security annotation, Quarkus checks whether the implementing method should inherit that annotation. If the methods involve generics/type variables, the Jandex-based check cannot decide safely and throws RuntimeException rather than silently skipping the check.
Source
Thrown at extensions/security/spi/src/main/java/io/quarkus/security/spi/SecurityTransformerBuildItem.java:232
&& securedMethod.parametersCount() == unsecuredMethod.parametersCount()) {
if (securedMethod.parametersCount() == 0) {
return true;
}
var securedMethodParams = securedMethod.parameterTypes();
if (hasNoTypeVariable(securedMethodParams)) {
// no type variables
return securedMethodParams.equals(unsecuredMethod.parameterTypes());
} else {
// methods with type variables are currently not supported
throw newUnableToDetermineIfSecuredException(securedMethod, unsecuredMethod);
}
}
return false;
}
private static RuntimeException newUnableToDetermineIfSecuredException(MethodInfo securedMethod,
MethodInfo unsecuredMethod) {
throw new RuntimeException(
"Unable to determine if the '%s' method should inherit security annotation of the '%s' method (generics not supported yet)"
.formatted(toString(unsecuredMethod), toString(securedMethod)));
}
private static boolean hasNoTypeVariable(List<Type> method) {
return method.stream().noneMatch(t -> {
if (t.kind() == TYPE_VARIABLE || t.kind() == Type.Kind.TYPE_VARIABLE_REFERENCE
|| t.kind() == Type.Kind.UNRESOLVED_TYPE_VARIABLE || t.kind() == Type.Kind.WILDCARD_TYPE) {
return true;
}
return t.kind() == PARAMETERIZED_TYPE && !hasNoTypeVariable(t.asParameterizedType().arguments());
});
}
private static Collection<ClassInfo> collectParentInterfaces(HashSet<ClassInfo> possiblySecuredInterfaces,
Set<DotName> securedInterfaceAnnotations, IndexView index) {
// this should avoid something like jakarta.data.repository.DataRepository
// because we only need inspect classes added by user for security annotationsView on GitHub (pinned to e1c734241f)
Solutions
- Re-annotate the implementing method directly with the security annotation instead of relying on inheritance from the generic interface method.
- Remove type variables from the method signature (use concrete types) so the inheritance check can succeed.
- Wrap the annotated generic method in a non-generic delegating bean that carries the security annotation.
- Avoid securing the interface method at all; secure the implementation.
Example fix
// before
interface Repo<T> { @RolesAllowed("admin") T find(long id); }
class UserRepo implements Repo<User> { public User find(long id) {...} }
// after
class UserRepo implements Repo<User> {
@RolesAllowed("admin")
public User find(long id) {...}
} Defensive patterns
Strategy: validation
Validate before calling
boolean genericsFree(java.lang.reflect.Method m) {
return m.getTypeParameters().length == 0
&& java.util.Arrays.stream(m.getGenericParameterTypes()).noneMatch(t -> t instanceof java.lang.reflect.TypeVariable)
&& !(m.getGenericReturnType() instanceof java.lang.reflect.TypeVariable);
} Prevention
- Put security annotations on concrete implementing methods, not generic interface methods
- Avoid type variables in secured method signatures
- If generics are needed, add a non-generic secured delegate method
When it happens
Trigger: A class implements/extends an interface with a @RolesAllowed/@Authenticated-annotated method where the implementation or interface method uses generic type parameters or type variables, defeating the hasNoTypeVariable checks during isImplementingSecuredMethod.
Common situations: Generic repositories/services like interface Repo<T> { @RolesAllowed("admin") T find(long id); } implemented by a CDI bean; frameworks generating generic implementations; upgrading Quarkus surfaces the previously-unsound generics case.
Related errors
- Private method '' cannot be annotated with the @PermissionCh
- Static method '' cannot be annotated with the @PermissionChe
- Interface '${declaringClass}' default method '${method}' has
- The '%s' CDI bean injection point was detected, but there is
- Type of injected Bean<T> does not match the type of the bean
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4138b253eb1dbd40.
Report an issue: GitHub.