passbolt/passbolt_api · error · InternalErrorException
Could not enable Duo MFA provider.
Error message
Could not enable Duo MFA provider.
What it means
Thrown in the constructor of MfaDuoVerifyDuoCodeService when the Duo SDK client cannot be obtained. The constructor either uses an injected client or calls MfaOrgSettingsGetSdkClientService::getOrFail(), and any Throwable from that lookup (missing/malformed Duo organization settings, missing credentials) is wrapped in this InternalErrorException.
Solutions
- Verify Duo organization settings exist via GET /mfa/policies/duo.json and re-save them if missing.
- Check that Duo client id, client secret, and api hostname are all present and non-empty in org settings.
- Inspect the previous exception ($th) in logs to identify the root failure from MfaDuoGetSdkClientService.
- Run the Duo settings health check endpoint to validate configuration before enabling Duo MFA.
Example fix
// before: constructing with no settings configured
$service = new MfaDuoVerifyDuoCodeService($uac, $authTokenType);
// after: guard by checking settings first
$orgSettings = new MfaOrgSettingsDuoService(MfaOrgSettings::get()->getSettings());
if (!MfaOrgSettings::get()->isProviderEnabled(MfaSettings::PROVIDER_DUO)) {
throw new BadRequestException('Duo provider is not configured.');
}
$service = new MfaDuoVerifyDuoCodeService($uac, $authTokenType); Defensive patterns
Strategy: try-catch
Validate before calling
$configured = MfaOrgSettings::get()->isProviderEnabled(MfaSettings::PROVIDER_DUO)
&& !empty(MfaOrgSettings::get()->getSettings()[MfaSettings::PROVIDER_DUO] ?? []); Try / catch
try {
$service = new MfaDuoVerifyDuoCodeService($uac, $authTokenType);
} catch (InternalErrorException $e) {
Log::error('Duo client init failed: ' . $e->getPrevious()?->getMessage());
throw new BadRequestException('Duo MFA is not properly configured.');
} Prevention
- Always complete Duo org settings configuration before enabling the provider.
- Run the Duo health-check validation after saving settings.
- Log and monitor the wrapped previous exception to detect config drift early.
When it happens
Trigger: Instantiating MfaDuoVerifyDuoCodeService without a pre-built client while Duo org settings are absent, incomplete (missing client id/secret/host), or the underlying getOrFail() throws for the given auth token type.
Common situations: Duo MFA organization settings were never configured or were deleted; partially saved Duo settings after a failed POST /mfa/policies/duo.json; corrupted org settings JSON in the database.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- Could not enable Duo MFA provider.
- Could not login using Duo MFA provider.
- An authentication token state is required.
- Could not create MFA verified cookie.
- Could not validate Duo configuration
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/7c8c7f2b7e79f3cd.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoVerifyDuoCodeService.php:58
*/
protected Client $duoClient;
/**
* MfaDuoVerifyService constructor.
*
* @param string $authTokenType The authentication token type, which determines which flow this is for
* @param \Duo\DuoUniversal\Client|null $client Duo SDK Client
* @throws \Cake\Http\Exception\InternalErrorException If it cannot create the Duo Sdk Client
*/
public function __construct(string $authTokenType, ?Client $client = null)
{
try {
$this->duoClient = $client ?? (new MfaDuoGetSdkClientService())->getOrFail(
new MfaOrgSettingsDuoService(MfaOrgSettings::get()->getSettings()),
$authTokenType
);
} catch (Throwable $th) {
throw new InternalErrorException(__('Could not enable Duo MFA provider.'), null, $th);
}
}
/**
* Verify the duo code and retrieve the associated authorization details from Duo.
*
* @param \App\Utility\UserAccessControl $uac The user access control
* @param string $duoCode The duo code
* @return bool
* @throws \Cake\Http\Exception\UnauthorizedException If an error occurred while retrieving the Duo authentication details
* @throws \Cake\Http\Exception\UnauthorizedException If the duo authentication origin endpoint (iss) does not match the duo hostname
* @throws \Cake\Http\Exception\UnauthorizedException if the duo authentication subscriber does not match the operator username
* @throws \Cake\Http\Exception\InternalErrorException If Duo doesn't return the authentication details as an array.
*/
public function verify(UserAccessControl $uac, string $duoCode): bool
{
$operatorUsername = $uac->getUsername();
$duoAuthenticationData = $this->requestDuoAuthenticationDetails($duoCode, $operatorUsername);View on GitHub (pinned to 31c1bbc10f)