quarkusio/quarkus · error · IllegalArgumentException
Source role must not be empty
Error message
Source role must not be empty
What it means
Inside HttpSecurityImpl.rolesMapping(Map), each map entry is validated by the anonymous BiConsumer; a source role that is the empty string ("") is rejected with IllegalArgumentException. A source role names the role the incoming identity must hold, so an empty name cannot be matched against any identity. The check runs per entry during forEach, before RolesMapping.of is built.
Source
Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java:245
@Override
public HttpPermission delete(String... paths) {
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));View on GitHub (pinned to e1c734241f)
Solutions
- Remove empty-string keys from the map before calling rolesMapping (filter entries with !sourceRole.isBlank()).
- Fix the config/data source so the source role name is present (e.g. correct the property key in application.properties).
- Add your own up-front validation to fail with a clearer message naming where the blank role came from.
Example fix
// before
Map<String, List<String>> mapping = parse(rawMappings); // may contain ""
httpSecurity.rolesMapping(mapping);
// after
Map<String, List<String>> mapping = rawMappings.entrySet().stream()
.filter(e -> !e.getKey().isBlank())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
httpSecurity.rolesMapping(mapping); Defensive patterns
Strategy: validation
Validate before calling
boolean allRolesNamed = roleToRoles.keySet().stream().noneMatch(k -> k.isBlank());
if (allRolesNamed) {
httpSecurity.rolesMapping(roleToRoles);
} Type guard
static boolean isValidRoleMapping(Map<String, List<String>> m) {
return m != null && m.entrySet().stream().allMatch(e ->
e.getKey() != null && !e.getKey().isBlank()
&& e.getValue() != null && !e.getValue().isEmpty());
} Try / catch
try {
httpSecurity.rolesMapping(mapping);
} catch (IllegalArgumentException e) {
throw new ConfigurationException("Invalid source role in mapping: " + e.getMessage(), e);
} Prevention
- Trim and validate role names when parsing them from properties or files.
- Filter out blank keys before building the mapping map.
- Log dropped entries so silently removed blank roles are visible.
When it happens
Trigger: rolesMapping(Map.of("", List.of("admin"))); building the map from split config strings where an empty key survived (e.g. "=admin" in a property value); a data-driven mapping file containing a blank role name.
Common situations: Parsing role mappings from application.properties where the key before '=' was omitted; user-supplied mapping files with blank lines parsed into empty keys; case-splitting a composite key like "source:target" where the source portion was empty.
Related errors
- Target roles for role '%s' 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/deab283e533dfc8f.
Report an issue: GitHub.