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

  1. Add the requested ACR value to cas.authn.oidc.acr.supported-values (or the equivalent configuration) and ensure the matching MFA provider is registered
  2. Align the RP's acr_values with the ACR names CAS advertises in discovery (acr_values_supported)
  3. Fix casing/spelling — ACR matching is exact containment
  4. 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

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


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)