spring-projects/spring-security · error · IllegalArgumentException
When when() includes
Error message
When when() includes {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities() must include {FactorGrantedAuthority.WEBAUTHN_AUTHORITY} What it means
MultiFactorAuthenticationSelector.selectImports validates @EnableMultiFactorAuthentication attributes: if when() includes MultiFactorCondition.WEBAUTHN_REGISTERED, the authorities() list must contain FactorGrantedAuthority.WEBAUTHN_AUTHORITY, otherwise it throws IllegalArgumentException. This ensures the WebAuthn registration condition has the matching factor authority to evaluate against.
Solutions
- Include FactorGrantedAuthority.WEBAUTHN_AUTHORITY in the authorities() attribute of @EnableMultiFactorAuthentication.
- Use the constant directly in code: FactorGrantedAuthority.WEBAUTHN_AUTHORITY, rather than a hand-typed string.
- Remove MultiFactorCondition.WEBAUTHN_REGISTERED from when() if WebAuthn factor enforcement is not intended.
- Align the annotation with the documented combination, e.g. @EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities = {FactorGrantedAuthority.WEBAUTHN_AUTHORITY}).
Example fix
// before
@EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities = {"OTP"})
// after
@EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED},
authorities = {FactorGrantedAuthority.WEBAUTHN_AUTHORITY}) Defensive patterns
Strategy: validation
Validate before calling
MultiFactorCondition[] when = ...; String[] authorities = ...;
if (Arrays.asList(when).contains(MultiFactorCondition.WEBAUTHN_REGISTERED)
&& !Arrays.asList(authorities).contains(FactorGrantedAuthority.WEBAUTHN_AUTHORITY)) {
throw new IllegalArgumentException("authorities() must include FactorGrantedAuthority.WEBAUTHN_AUTHORITY");
} Try / catch
try {
context = applicationContext; // annotation processed at startup
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("WEBAUTHN_AUTHORITY")) {
throw new ConfigurationException("Fix @EnableMultiFactorAuthentication attributes", e);
}
throw e;
} Prevention
- Use the FactorGrantedAuthority.WEBAUTHN_AUTHORITY constant, not a hand-written string
- Keep when() and authorities() attributes consistent
- Review annotation attributes when upgrading Spring Security versions
- Add an integration test that boots the annotation-processed context
When it happens
Trigger: Annotating @EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities = {...}) where the authorities array omits FactorGrantedAuthority.WEBAUTHN_AUTHORITY (note: the check compares the given strings against the constant, so the constant's string value must be present exactly).
Common situations: Typo or custom string in authorities() instead of the exact WEBAUTHN_AUTHORITY value; enabling the WebAuthn condition during a migration from password-only multi-factor config; copy-pasted annotation attributes from a non-WebAuthn example.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- A filter chain that matches any request
- Can not set rememberMeCookieName and custom…
- Cannot apply to already built object
- Cannot configure both a CorsConfigurationSource and a…
- Cannot load keys from store:
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/6fa42c192838f340.
Report an issue: GitHub.
Appendix: source
Thrown at config/src/main/java/org/springframework/security/config/annotation/authorization/MultiFactorAuthenticationSelector.java:54
* {@link org.springframework.security.core.authority.FactorGrantedAuthority#WEBAUTHN_AUTHORITY}
* and throws an {@link IllegalArgumentException} if not.
*
* @author Rob Winch
* @since 7.0
* @see EnableMultiFactorAuthentication
*/
class MultiFactorAuthenticationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
Map<String, Object> multiFactorAuthenticationAttrs = metadata
.getAnnotationAttributes(EnableMultiFactorAuthentication.class.getName());
String[] authorities = (String[]) multiFactorAuthenticationAttrs.getOrDefault("authorities", new String[0]);
MultiFactorCondition[] when = (MultiFactorCondition[]) multiFactorAuthenticationAttrs.getOrDefault("when",
new MultiFactorCondition[0]);
boolean hasWebAuthn = Arrays.asList(when).contains(MultiFactorCondition.WEBAUTHN_REGISTERED);
if (hasWebAuthn && !Arrays.asList(authorities).contains(FactorGrantedAuthority.WEBAUTHN_AUTHORITY)) {
throw new IllegalArgumentException("When when() includes " + MultiFactorCondition.WEBAUTHN_REGISTERED
+ ", authorities() must include " + FactorGrantedAuthority.WEBAUTHN_AUTHORITY);
}
List<String> imports = new ArrayList<>(3);
if (authorities.length > 0) {
imports.add(AuthorizationManagerFactoryConfiguration.class.getName());
if (hasWebAuthn) {
imports.add(WhenWebAuthnRegisteredMfaConfiguration.class.getName());
}
}
imports.add(EnableMfaFiltersConfiguration.class.getName());
return imports.toArray(new String[imports.size()]);
}
}
View on GitHub (pinned to 96852e8860)