quarkusio/quarkus · error · RuntimeException
Unsupported @Roles field/getter type: ${rolesType}
Error message
Unsupported @Roles field/getter type: ${rolesType} What it means
The @Roles field/getter type must be String, List<X>, Collection<X>, or Set<X>. Arrays and any other type kind (primitive, other classes, wildcard types, etc.) are not supported by the build-time role handler, so the build fails.
Source
Thrown at extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java:206
// }
bc.forEach(role, (loopBody, var) -> {
Expr roleElement;
if (rolesFieldOrMethod != null) {
roleElement = rolesFieldOrMethod.readValue(loopBody, var);
} else {
roleElement = var;
}
loopBody.invokeStatic(
MethodDesc.of(JpaIdentityProviderUtil.class, "addRoles", void.class,
QuarkusSecurityIdentity.Builder.class, String.class),
builderVar, roleElement);
});
handledRole = true;
}
break;
}
if (!handledRole) {
throw new RuntimeException("Unsupported @Roles field/getter type: " + rolesType);
}
// return builder.build()
bc.return_(bc.invokeVirtual(
MethodDesc.of(QuarkusSecurityIdentity.Builder.class,
"build",
QuarkusSecurityIdentity.class),
builderVar));
}
private static MethodDesc getUtilMethod(String passwordProviderMethod) {
return MethodDesc.of(JpaIdentityProviderUtil.class, passwordProviderMethod,
Password.class, String.class);
}
private static MethodDesc passwordActionMethod() {
return MethodDesc.of(JpaIdentityProviderUtil.class, "passwordAction", void.class, PasswordType.class);
}View on GitHub (pinned to e1c734241f)
Solutions
- Change the @Roles field/getter type to String, List<String>, Set<String>, or Collection<String>.
- If roles are entities, use List<RoleEntity>/Set<RoleEntity> with a @RoleValue on the role class.
- If using a generic collection, always supply type parameters (e.g. List<String>, not raw List).
- Convert arrays (String[]) to List via entity mapping or change the JPA mapping to @ElementCollection.
Example fix
// before @Roles public String[] roles; // after @Roles @ElementCollection public List<String> roles;
Defensive patterns
Strategy: validation
Validate before calling
Class<?> t = rolesField.getType();
boolean ok = t == String.class || List.class.isAssignableFrom(t)
|| Set.class.isAssignableFrom(t) || Collection.class.isAssignableFrom(t);
if (!ok) throw new IllegalStateException("@Roles must be String or List/Set/Collection"); Prevention
- Use String, List<String>, Set<String>, or Collection<String> for @Roles.
- Never use arrays or raw generics for the roles field.
- Use @ElementCollection for entity-backed role collections.
When it happens
Trigger: Annotating a field/getter with @Roles whose declared type is String[], an array of entities, a Map, a raw/non-parameterized generic type (whose kind is CLASS but not String), or any other unsupported type.
Common situations: Using String[] roles from legacy code; using a raw List without type parameters (element type unknown -> handledRole stays false); using Optional<List<String>> or custom collection types not in the supported trio.
Related errors
- Unsupported field type for multipart response mapping: " + t
- Unsupported type '" + notBodyTargetType + "' used with '" +
- Unknown password type: ${passwordType}
- You can only annotate one field or method with @${annotation
- The role element type must be indexed by Jandex: ${elementTy
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4ffc42bcc682cc52.
Report an issue: GitHub.