NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Every exception extends the abstract TwoFactorException, so you can handle specific cases first and catch the whole family last:

use RoundlyConsulting\TwoFactor\Exceptions\InvalidTwoFactorCodeException;
use RoundlyConsulting\TwoFactor\Exceptions\TwoFactorException;
use RoundlyConsulting\TwoFactor\Exceptions\TwoFactorNotPendingException;
use RoundlyConsulting\TwoFactor\Facades\TwoFactor;

try {
    TwoFactor::for($user)->confirm($request->string('code')->toString());
} catch (InvalidTwoFactorCodeException $e) {
    // wrong code — ask again
} catch (TwoFactorNotPendingException $e) {
    // nothing pending, or 2FA is already enabled
} catch (TwoFactorException $e) {
    // any other package failure
}
ExceptionThrown when
TwoFactorExceptionAbstract base (a RuntimeException) — catch it for the whole family.
InvalidTwoFactorCodeExceptionconfirm() receives a wrong code.
TwoFactorNotPendingExceptionConfirming with no pending enrolment — including when 2FA is already enabled.
TwoFactorAlreadyEnabledExceptionStarting enrolment for a user who already has 2FA enabled.
TwoFactorRateLimitedExceptionThe built-in limiter locked the challenge; carries secondsUntilAvailable.
InvalidTwoFactorConfigExceptionAn unknown algorithm, recovery_codes.storage or replay_guard; an out-of-range or non-integer digits, period, window, secret_length, attempts.*, recovery_codes.count or cache.ttl value; an attempts that is neither an array nor null; a non-string issuer or cache store; or a non-string table or column name.
InvalidBase32ExceptionA secret is not valid base32 and cannot be decoded.
TwoFactorAssertionFailedExceptionA TwoFactorFake assertion failed.

crypto-for-laravel’s own exceptions never escape: a base32 decoding failure becomes InvalidBase32Exception, and an OTP parameter or length failure becomes InvalidTwoFactorConfigException.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.