quarkusio/quarkus · error · IllegalArgumentException
Target roles for role '%s' must not be empty
Error message
Target roles for role '%s' must not be empty
What it means
The per-entry BiConsumer in rolesMapping(Map) also rejects entries whose target-roles list is null or empty, using a formatted message that names the offending source role. Target roles are the roles granted to identities holding the source role; an entry with no targets is meaningless and would produce a dead policy, so the library fails fast during RolesMapping.of preparation.
Source
Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java:248
return path(paths).methods("DELETE");
}
@Override
public HttpSecurity rolesMapping(Map<String, List<String>> roleToRoles) {
if (rolesMapping != null) {
throw new IllegalStateException("Roles mapping is already configured");
}
if (roleToRoles == null || roleToRoles.isEmpty()) {
throw new IllegalArgumentException("Roles must not be empty");
}
roleToRoles.forEach(new BiConsumer<String, List<String>>() {
@Override
public void accept(String sourceRole, List<String> targetRoles) {
if (sourceRole.isEmpty()) {
throw new IllegalArgumentException("Source role must not be empty");
}
if (targetRoles == null || targetRoles.isEmpty()) {
throw new IllegalArgumentException("Target roles for role '%s' must not be empty".formatted(sourceRole));
}
}
});
this.rolesMapping = RolesMapping.of(roleToRoles);
return this;
}
@Override
public HttpSecurity rolesMapping(String sourceRole, List<String> targetRoles) {
if (sourceRole == null) {
throw new IllegalArgumentException("Source role must not be null");
}
if (targetRoles == null) {
throw new IllegalArgumentException("Target roles for role '%s' must not be null".formatted(sourceRole));
}
return rolesMapping(Map.of(sourceRole, targetRoles));
}View on GitHub (pinned to e1c734241f)
Solutions
- Ensure every entry in the map has at least one target role before calling rolesMapping; drop entries with null/empty targets.
- If the target list is derived from config, skip the whole entry (or the whole call) when the list resolves to empty.
- Fix the data source so the source role has an explicit, non-empty list of target roles.
Example fix
// before
mapping.put("user", filteredRoles); // filteredRoles may be empty
httpSecurity.rolesMapping(mapping);
// after
if (!filteredRoles.isEmpty()) {
mapping.put("user", filteredRoles);
}
if (!mapping.isEmpty()) {
httpSecurity.rolesMapping(mapping);
} Defensive patterns
Strategy: validation
Validate before calling
boolean validTargets = roleToRoles.values().stream()
.allMatch(v -> v != null && !v.isEmpty());
if (validTargets) {
httpSecurity.rolesMapping(roleToRoles);
} Type guard
static boolean hasTargets(Map.Entry<String, List<String>> e) {
return e.getValue() != null && !e.getValue().isEmpty();
} Try / catch
try {
httpSecurity.rolesMapping(mapping);
} catch (IllegalArgumentException e) {
// message names the offending source role
log.error("Role mapping rejected: " + e.getMessage());
} Prevention
- Drop entries whose target list is null/empty before registering the mapping.
- When filtering target roles, remove the whole entry if the result is empty.
- Validate data-driven mappings (JSON/DB) at load time.
When it happens
Trigger: rolesMapping(Map.of("user", List.of())) or rolesMapping("user", null) delegated through Map.of("user", null) (note Map.of itself would NPE on a null value, so null lists typically arrive via HashMap); building lists dynamically where an empty list remained after filtering.
Common situations: Assembling target roles from config where an optional roles list was absent; stripping roles the application does not recognize and ending up with an empty list; JDBC/JSON-driven mappings with an empty targets array.
Related errors
- Source role must not be empty
- Source role must not be null
- Target roles for role '%s' must not be null
- Target role for role '%s' must not be null
- Roles must not be empty
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2fd2e51b617d9020.
Report an issue: GitHub.