{"record":{"id":"e1af0861c89494d9","repo":"apereo/cas","slug":"no-multifactor-authentication-providers-are-specif","errorCode":null,"errorMessage":"No multifactor authentication providers are specified to handle risk-based authentication","messagePattern":"No multifactor authentication providers are specified to handle risk-based authentication","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-electrofence/src/main/java/org/apereo/cas/impl/plans/MultifactorAuthenticationContingencyPlan.java","lineNumber":51,"sourceCode":"\n    @Override\n    protected AuthenticationRiskContingencyResponse executeInternal(final Authentication authentication,\n                                                                    final RegisteredService service,\n                                                                    final AuthenticationRiskScore score,\n                                                                    final HttpServletRequest request) {\n        var id = casProperties.getAuthn().getAdaptive().getRisk().getResponse().getMfaProvider();\n        if (StringUtils.isBlank(id)) {\n            LOGGER.debug(\"No explicit multifactor authentication provider is defined to handle risk-based authentication.\");\n            val providerMap = MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);\n            if (providerMap.isEmpty()) {\n                LOGGER.warn(\"No multifactor authentication providers are available in the application context. Authentication is blocked\");\n                throw new AuthenticationException(new RiskyAuthenticationException());\n            }\n\n            if (providerMap.size() == 1) {\n                id = providerMap.values().iterator().next().getId();\n            } else {\n                LOGGER.warn(\"No multifactor authentication providers are specified to handle risk-based authentication\");\n                throw new AuthenticationException(new MultifactorAuthenticationProviderAbsentException());\n            }\n        }\n\n        LOGGER.debug(\"Attempting to handle risk-based authentication via multifactor authentication provider [{}]\", id);\n        val attributeName = casProperties.getAuthn().getAdaptive().getRisk().getResponse().getRiskyAuthenticationAttribute();\n        val newAuthn = DefaultAuthenticationBuilder.newInstance(authentication)\n            .addAttribute(attributeName, Boolean.TRUE)\n            .build();\n        LOGGER.debug(\"Updated authentication to remember risk-based authentication via [{}]\", attributeName);\n        authentication.updateAttributes(newAuthn);\n        return new AuthenticationRiskContingencyResponse(new Event(this, id));\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":66,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-electrofence/src/main/java/org/apereo/cas/impl/plans/MultifactorAuthenticationContingencyPlan.java#L33-L66","documentation":"When no explicit risk-response MFA provider is configured, executeInternal() discovers all available MFA providers. If exactly one is found it is used automatically; if more than one is available and none was specified, CAS cannot choose, logs this warning, and throws AuthenticationException wrapping MultifactorAuthenticationProviderAbsentException, blocking authentication. The deployer must explicitly select a provider when several exist.","triggerScenarios":"Risky authentication handled by MultifactorAuthenticationContingencyPlan while cas.authn.adaptive.risk.response.mfaProvider is blank and the context contains two or more registered MultifactorAuthenticationProvider beans (e.g. both Duo and TOTP configured).","commonSituations":"Overlay enables multiple MFA modules (common when mfa-duo and mfa-totp coexist) but the operator forgot to set the risk-response provider id; a newly added MFA module pushed the provider count from 1 to 2, breaking previously working implicit selection.","solutions":["Set cas.authn.adaptive.risk.response.mfa-provider to the id of the intended provider (e.g. mfa-duo).","Verify the configured id matches a registered provider's id from MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders.","Disable or remove the unwanted MFA module so only one provider remains registered.","Alternatively rely on registered-service MFA policies and configure the risk response to a definite provider to avoid ambiguity."],"exampleFix":"// before: multiple providers, none selected for risk response\ncas.authn.mfa.duo.enabled=true\ncas.authn.mfa.totp.enabled=true\n// after: explicitly select the provider for risky auth\ncas.authn.mfa.duo.enabled=true\ncas.authn.mfa.totp.enabled=true\ncas.authn.adaptive.risk.response.mfa-provider=mfa-duo","handlingStrategy":"validation","validationCode":"val providers = MultifactorAuthenticationUtils\n    .getAvailableMultifactorAuthenticationProviders(applicationContext);\nval configured = casProperties.getAuthn().getAdaptive().getRisk().getResponse().getMfaProvider();\nif (providers.size() > 1 && StringUtils.isBlank(configured)) {\n    throw new IllegalStateException(\n        \"Multiple MFA providers [\" + providers.keySet() + \"] available; set risk response mfa-provider\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    contingencyPlan.handle(event, authentication, service, request);\n} catch (AuthenticationException e) {\n    if (e.hasExceptionOfType(MultifactorAuthenticationProviderAbsentException.class)) {\n        LOGGER.error(\"Ambiguous risk-response MFA setup; no provider id configured\");\n        throw new HttpRequestException(\"MFA provider unresolvable\", HttpStatus.SERVICE_UNAVAILABLE);\n    }\n    throw e;\n}","preventionTips":["Always set cas.authn.adaptive.risk.response.mfa-provider in multi-MFA deployments.","After adding any new MFA module, re-verify the risk response provider id is still valid.","Document provider ids (mfa-duo, mfa-totp, ...) in deployment configuration templates.","Validate config at boot with a check that the configured provider id exists in the provider registry."],"tags":["mfa","risk-authentication","electrofence","ambiguous-config"],"backgroundTag":"missing-required-config-field","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}