quarkusio/quarkus · error · RuntimeException
You can only annotate one field or method with @${annotation
Error message
You can only annotate one field or method with @${annotation} What it means
The JPA security extension expects exactly one element in the application indexed by Jandex to carry a given annotation (such as @Username, @Password, or @Roles). If more than one field or method carries that annotation, the build-time generator cannot decide which one to use and aborts the build.
Source
Thrown at extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java:135
trueBranch.returnNull();
});
// Builder builder = JpaIdentityProviderUtil.trusted(request);
Expr builder = bc.invokeStatic(MethodDesc.of(JpaIdentityProviderUtil.class,
"trusted",
QuarkusSecurityIdentity.Builder.class,
TrustedAuthenticationRequest.class),
requestParam);
LocalVar builderVar = bc.localVar("builder", QuarkusSecurityIdentity.Builder.class, builder);
setupRoles(index, jpaSecurityDefinition, panacheEntityPredicate, userVar, builderVar, bc);
}
static AnnotationTarget getSingleAnnotatedElement(Index index, DotName annotation) {
List<AnnotationInstance> annotations = index.getAnnotations(annotation);
if (annotations.isEmpty()) {
return null;
} else if (annotations.size() > 1) {
throw new RuntimeException("You can only annotate one field or method with @" + annotation);
}
return annotations.get(0).target();
}
private static void setupRoles(Index index, JpaSecurityDefinition jpaSecurityDefinition,
PanacheEntityPredicateBuildItem panacheEntityPredicate, Expr userVar,
LocalVar builderVar, BlockCreator bc) {
Expr role = jpaSecurityDefinition.roles.readValue(bc, userVar);
// role: user.getRole()
boolean handledRole = false;
Type rolesType = jpaSecurityDefinition.roles.type();
switch (rolesType.kind()) {
case ARRAY:
// FIXME: support non-JPA-backed array roles?
break;
case CLASS:
if (rolesType.name().equals(DotNames.STRING)) {
// JpaIdentityProviderUtil.addRoles(builder, :role)View on GitHub (pinned to e1c734241f)
Solutions
- Keep the annotation on exactly one field or method in the whole application; remove duplicate @Username/@Password/@Roles annotations.
- If you need multiple user representations, annotate only the @UserDefinition entity and remove annotations from other classes.
- Move duplicate annotations into plain fields (no security annotations) if they are used for non-authentication purposes.
Example fix
// before: two annotated classes
@UserDefinition public class User { @Roles public String role; }
public class AdminUser { @Roles public String role; }
// after
@UserDefinition public class User { @Roles public String role; }
public class AdminUser { public String role; } Defensive patterns
Strategy: validation
Validate before calling
// before build: ensure single occurrence of each security annotation
long count = Stream.of(entityClasses)
.flatMap(c -> Arrays.stream(c.getDeclaredFields()))
.filter(f -> f.isAnnotationPresent(Username.class))
.count();
if (count > 1) throw new IllegalStateException("@Username must appear on exactly one member"); Prevention
- Annotate security members only on the single @UserDefinition entity.
- Search the codebase for @Username/@Password/@Roles before adding new ones.
- Remove leftover annotations after refactors.
When it happens
Trigger: Declaring @Username, @Password, or @Roles on more than one field or getter — across all classes in the application index, not just within one entity — then building the application with a @UserDefinition entity present.
Common situations: Having a @UserDefinition entity plus another class (e.g. an admin entity or DTO) also annotated with @Roles or @Username; leftover annotations after refactoring; multiple user entity candidates kept around 'temporarily'.
Related errors
- The role element type must be indexed by Jandex: ${elementTy
- You can only annotate one class with @UserDefinition
- Invalid type:
- Injected class not found in index:
- The original implementation class of a gRPC service not foun
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e91fe86263288ca9.
Report an issue: GitHub.