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

  1. Include FactorGrantedAuthority.WEBAUTHN_AUTHORITY in the authorities() attribute of @EnableMultiFactorAuthentication.
  2. Use the constant directly in code: FactorGrantedAuthority.WEBAUTHN_AUTHORITY, rather than a hand-typed string.
  3. Remove MultiFactorCondition.WEBAUTHN_REGISTERED from when() if WebAuthn factor enforcement is not intended.
  4. 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

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


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)