quarkusio/quarkus · error · IllegalArgumentException
Roles cannot be null or empty
Error message
Roles cannot be null or empty
What it means
MTLS.Builder.rolesMapping(String, Set<String>) throws IllegalArgumentException when the roles set is null or empty. Each certificate attribute value must map to at least one role for the certificate-to-roles mapper to be meaningful.
Source
Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/security/MTLS.java:242
* @see #rolesMapping(String, Set) for more information
*/
public Builder rolesMapping(String certificateAttributeValue, String... roles) {
return rolesMapping(certificateAttributeValue, Set.of(roles));
}
/**
* Adds a certificate attribute value to roles mapping.
* The certificate attribute itself can be configured with the {@link #certificateAttribute} method.
*
* @param certificateAttributeValue {@link AuthRuntimeConfig#certificateRoleAttribute()} values that will be
* mapped to the {@link SecurityIdentity} roles
* @param roles {@link SecurityIdentity#getRoles()}
* @return CertificateRolesBuilder
*/
public Builder rolesMapping(String certificateAttributeValue, Set<String> roles) {
Objects.requireNonNull(certificateAttributeValue);
if (roles == null || roles.isEmpty()) {
throw new IllegalArgumentException("Roles cannot be null or empty");
}
assertCertificateToRolesMapperNotSetYet();
if (certificateAttributeValueToRoles == null) {
certificateAttributeValueToRoles = new HashMap<>();
}
certificateAttributeValueToRoles.computeIfAbsent(certificateAttributeValue, new Function<String, Set<String>>() {
@Override
public Set<String> apply(String ignored) {
return new HashSet<>();
}
}).addAll(roles);
return this;
}
private void assertCertificateToRolesMapperNotSetYet() {
if (certificateToRolesMapper != null) {
throw new IllegalStateException(
"The certificate to roles mapper is already configured with the 'certificateToRolesMapper' method");View on GitHub (pinned to e1c734241f)
Solutions
- Pass a non-empty Set of roles for each certificate attribute value
- Skip calling rolesMapping when no roles are available
- Fix the role source (config/lookup) to return actual role names
Example fix
// before
builder.rolesMapping("CN=admin", rolesFromConfig); // may be empty
// after
if (rolesFromConfig != null && !rolesFromConfig.isEmpty()) {
builder.rolesMapping("CN=admin", rolesFromConfig);
} Defensive patterns
Strategy: validation
Validate before calling
if (roles == null || roles.isEmpty()) {
throw new IllegalStateException("rolesMapping requires at least one role for " + certAttrValue);
}
builder.rolesMapping(certAttrValue, roles); Type guard
boolean hasRoles(Set<String> r) { return r != null && !r.isEmpty(); } Prevention
- Validate role config at startup so empty sets never reach the builder
- Skip rolesMapping entries with no roles instead of registering them
- Assert role sources return defaults rather than null/empty
When it happens
Trigger: Calling rolesMapping(attrValue, null) or rolesMapping(attrValue, Set.of()) — e.g. when the role list comes from empty config or a failed lookup.
Common situations: Empty roles config entry; a role-list parsing step that filtered everything out; DB/property lookup returning no roles for a certificate attribute.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- An attachment must contain either a file or a raw data
- `count` must be strictly positive
- TLS configuration name has already been configured with the
- Client authentication cannot be disabled with this API
- name cannot be null
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1936d0576871783f.
Report an issue: GitHub.