passbolt/passbolt_api · error · RecordNotFoundException

MFA setting OTP provisioning uri is not set.

Error message

MFA setting OTP provisioning uri is not set.

What it means

getOtpProvisioningUri() (MfaAccountSettingsTotpTrait) returns the stored TOTP provisioning URI. It throws RecordNotFoundException when settings['totp']['otpProvisioningUri'] is not set, i.e. TOTP was never configured for the account or the URI was never persisted.

Solutions

  1. Ensure TOTP setup completed via MfaForm/verify flow, which persists the provisioning URI before it is read.
  2. Check isset($this->settings['totp']['otpProvisioningUri']) before calling, or expose an has method.
  3. Catch RecordNotFoundException and redirect the user to (re)start TOTP enrollment.
  4. If enrolling a user who already has TOTP, regenerate the provisioning URI via the TOTP setup service instead of reading stale settings.

Example fix

// before
$uri = $mfaAccountSettings->getOtpProvisioningUri();
// after
try {
    $uri = $mfaAccountSettings->getOtpProvisioningUri();
} catch (\Cake\Datasource\Exception\RecordNotFoundException $e) {
    return $this->redirect(['action' => 'setupTotp']); // restart enrollment
}
Defensive patterns

Strategy: try-catch

Validate before calling

$uri = null;
try { $uri = $s->getOtpProvisioningUri(); } catch (RecordNotFoundException $e) {}

Try / catch

try { $uri = $s->getOtpProvisioningUri(); } catch (\Cake\Datasource\Exception\RecordNotFoundException $e) { return redirect to TOTP setup; }

Prevention

When it happens

Trigger: Calling getOtpProvisioningUri() on account settings where the totp provider entry lacks the OTP_PROVISIONING_URI key — before TOTP setup completes or after settings saved without the URI.

Common situations: Rendering the QR code page for a user whose TOTP enrollment was interrupted; reading settings from a store where the URI key was stripped; calling it for users who use yubikey instead of totp; tests constructing partial settings arrays.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/4007d13a48e7d79c. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Utility/MfaAccountSettingsTotpTrait.php:32

 * @link          https://www.passbolt.com Passbolt(tm)
 * @since         2.5.0
 */
namespace Passbolt\MultiFactorAuthentication\Utility;

use Cake\Datasource\Exception\RecordNotFoundException;

trait MfaAccountSettingsTotpTrait
{
    /**
     * Return OTP provisioning url
     *
     * @throws \Cake\Datasource\Exception\RecordNotFoundException if URI is not set
     * @return string
     */
    public function getOtpProvisioningUri(): string
    {
        if (!isset($this->settings[MfaSettings::PROVIDER_TOTP][MfaAccountSettings::OTP_PROVISIONING_URI])) {
            throw new RecordNotFoundException(__('MFA setting OTP provisioning uri is not set.'));
        }

        return $this->settings[MfaSettings::PROVIDER_TOTP][MfaAccountSettings::OTP_PROVISIONING_URI];
    }

    /**
     * Return true if otp provisioning uri is set
     *
     * @return bool
     */
    public function isOtpProvisioningUriSet(): bool
    {
        return isset($this->settings[MfaSettings::PROVIDER_TOTP][MfaAccountSettings::OTP_PROVISIONING_URI]);
    }
}

View on GitHub (pinned to 31c1bbc10f)