apereo/cas · warning
ACR [ ] is not defined as a supported ACR in CAS…
Error message
ACR [{}] is not defined as a supported ACR in CAS configuration, [{}] What it means
When an OIDC authorization request carries an acr_values claim, OidcMultifactorAuthenticationTrigger.isActivated checks each requested ACR against the supported ACR values configured for CAS (global + service-level). If none of the requested values is supported, CAS logs this warning and returns Optional.empty() — the MFA trigger is bypassed and authentication continues without the requested MFA.
Solutions
- Add the requested ACR value to cas.authn.oidc.acr.supported-values (or the equivalent configuration) and ensure the matching MFA provider is registered
- Align the RP's acr_values with the ACR names CAS advertises in discovery (acr_values_supported)
- Fix casing/spelling — ACR matching is exact containment
- Set a default MFA trigger if unauthenticated ACR requests should still force MFA
Example fix
// before GET /oidc/authorize?...&acr_values=mfa_totp # not in supported ACRs # cas.authn.oidc.acr.supported-values=mfa-duo,mfa-webauthn // after cas.authn.oidc.acr.supported-values=mfa-duo,mfa-webauthn,mfa-totp # or request acr_values=mfa-duo
Defensive patterns
Strategy: validation
Validate before calling
const supported = discovery.acr_values_supported ?? [];
const requested = acrValues.split(' ');
const usable = requested.filter(a => supported.includes(a));
if (usable.length === 0) console.warn(`None of [${requested}] are supported; MFA will be skipped: ${supported}`); Type guard
function hasSupportedAcr(requestedAcrs, supportedAcrs) {
return requestedAcrs.split(' ').some(a => supportedAcrs.includes(a));
} Prevention
- Read acr_values_supported from discovery before sending acr_values
- Keep supported-values in sync with enabled MFA providers
- Match ACR strings exactly (case-sensitive)
- Handle the 'no MFA triggered' path gracefully in the RP
When it happens
Trigger: Authorization request with acr_values whose space-delimited entries match none of the ACRs resolved from getSupportedAcrValues (cas.authn.oidc.acr supported values / registered service acr policy).
Common situations: RPs requesting vendor-specific ACR strings not configured in CAS; typos or wrong case in acr_values; MFA provider removed/upgraded so its ACR no longer matches; service-level ACR overrides not updated.
Related errors
- Not all requested multifactor providers could be found…
- List of candidate multifactor authentication providers is…
- Unable to use 'none' for the user-info signing algorithm
- Unable to use 'none' as user-info encryption algorithm
- Service with client id is configured to encrypt tokens, yet…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/0429fe969c542ee4.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/flow/OidcMultifactorAuthenticationTrigger.java:74
private final FactoryBean<OidcServerDiscoverySettings> discoverySettingsFactory;
private int order = Ordered.LOWEST_PRECEDENCE;
@Override
public Optional<MultifactorAuthenticationProvider> isActivated(final Authentication authentication,
final RegisteredService registeredService,
final HttpServletRequest request,
final HttpServletResponse response,
final Service service) {
val acr = getAuthenticationClassReference(request, response);
if (StringUtils.isBlank(acr)) {
LOGGER.debug("No ACR provided in the authentication request");
return Optional.empty();
}
val supportedAcrValues = getSupportedAcrValues(authentication, registeredService, request);
val values = List.of(org.springframework.util.StringUtils.delimitedListToStringArray(acr, " "));
if (values.stream().noneMatch(supportedAcrValues::contains)) {
LOGGER.warn("ACR [{}] is not defined as a supported ACR in CAS configuration, [{}]", acr, supportedAcrValues);
return Optional.empty();
}
val providerMap = MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);
if (providerMap.isEmpty()) {
LOGGER.error("No multifactor authentication providers are available in the application context to handle [{}]", values);
throw new AuthenticationException(new MultifactorAuthenticationProviderAbsentException());
}
val authnContexts = casProperties.getAuthn().getOidc().getCore().getAuthenticationContextReferenceMappings();
val mappings = CollectionUtils.convertDirectedListToMap(authnContexts);
val mappedAcrValues = values
.stream()
.map(acrValue -> mappings.getOrDefault(acrValue, acrValue))
.collect(Collectors.toList());
LOGGER.debug("Mapped ACR values are [{}] to compare against [{}]", mappedAcrValues, providerMap.values());
return providerMap.values()
.stream()View on GitHub (pinned to e7288fc434)