passbolt/passbolt_api · error · CustomValidationException
Could not validate multi-factor authentication provider…
Error message
Could not validate multi-factor authentication provider configuration.
What it means
After validating each individual provider's configuration, MfaOrgSettings::validate() aggregates per-provider errors and throws CustomValidationException (with the error details as its second argument) if any provider failed. It signals that at least one provider's org-level configuration is invalid.
Solutions
- Inspect the exception's validation errors (its second argument) to identify which provider and field failed, fix those values, and resubmit.
- Run the provider form validation client-side or in the service before calling save().
- Verify each provider's config against the provider form rules: issuer format for totp, numeric clientId and non-empty secretKey for yubikey.
- Catch CustomValidationException and surface $e->getErrors() to the admin UI.
- exampleFixPlaceholder
Example fix
// before
try {
$orgSettings->save($data);
} catch (\App\Error\Exception\CustomValidationException $e) {
throw new InternalErrorException($e->getMessage());
}
// after
try {
$orgSettings->save($data);
} catch (\App\Error\Exception\CustomValidationException $e) {
throw new BadRequestException($e->getMessage(), 400, $e); // include $e->getErrors() in response
} Defensive patterns
Strategy: try-catch
Try / catch
try { $orgSettings->save($data); } catch (\App\Error\Exception\CustomValidationException $e) { $errors = $e->getErrors(); /* surface per-provider errors to client */ } Prevention
- Always inspect the exception's error details, not just the message
- Run each provider's form validation before assembling the save payload
- Keep org provider config values aligned with the provider form rules (issuer, clientId, secretKey formats)
When it happens
Trigger: Calling validate()/save() where a per-provider form (e.g. MfaOrgSettingsTotpForm or yubikey form) fails validation — e.g. invalid TOTP issuer, missing/invalid yubikey clientId or secretKey format — populating $results with errors.
Common situations: Admin saving org MFA settings with a typo in provider config values; yubikey clientId/secretKey failing validation after a change at YubiCo; invalid issuer/OTP digits in TOTP org settings; API clients posting raw config that never passed client-side validation.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Could not validate Duo configuration
- Could not validate Yubikey configuration.
- It is not possible to create an authentication token for…
- Something went wrong when validating the one-time password.
- The authentication token should be a valid UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/b57c003b4ee4e313.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Utility/MfaOrgSettings.php:316
(new MfaOrgSettingsDuoService($data))->validateDuoSettings($client, $skipHealthcheck === false);
} catch (CustomValidationException $exception) {
$errors = $exception->getErrors();
}
break;
case MfaSettings::PROVIDER_TOTP:
// Nothing else to validate
break;
default:
$errors[$provider]['invalidProvider'] = __('Unknown MFA provider: {0}.', $provider);
break;
}
if (isset($errors[$provider])) {
$results[$provider] = $errors[$provider];
}
}
if (count($results) !== 0) {
$msg = __('Could not validate multi-factor authentication provider configuration.');
throw new CustomValidationException($msg, $results);
}
return true;
}
/**
* Save a user provided org settings in database
*
* @throws \App\Error\Exception\CustomValidationException in case of validation error
* @throws \Cake\Http\Exception\InternalErrorException
* @param array $data user provided input
* @param \App\Utility\UserAccessControl $uac user access control
* @param \Duo\DuoUniversal\Client|null $client Duo SDK Client
* @param array $options Options used to save & validate organisation settings
* @return void
*/
public function save(array $data, UserAccessControl $uac, ?Client $client = null, array $options = []): void
{View on GitHub (pinned to 31c1bbc10f)