BookStackApp/BookStack · info · ConfirmationEmailException
errors.email_already_confirmed
Error message
errors.email_already_confirmed
What it means
ConfirmationEmailException thrown by EmailConfirmationService::sendConfirmation when the given user's email_confirmed flag is already true. Sending a confirmation email to an already-confirmed account is meaningless, so the service aborts with a message and redirects to /login.
Source
Thrown at app/Access/EmailConfirmationService.php:25
use BookStack\Users\Models\User;
use Exception;
class EmailConfirmationService extends UserTokenService
{
protected string $tokenTable = 'email_confirmations';
protected int $expiryTime = 24;
/**
* Create new confirmation for a user,
* Also removes any existing old ones.
*
* @throws ConfirmationEmailException
* @throws Exception
*/
public function sendConfirmation(User $user): void
{
if ($user->email_confirmed) {
throw new ConfirmationEmailException(trans('errors.email_already_confirmed'), '/login');
}
$this->deleteByUser($user);
$token = $this->createTokenForUser($user);
$user->notify(new ConfirmEmailNotification($token));
}
/**
* Check if confirmation is required in this instance.
*/
public function confirmationRequired(): bool
{
return setting('registration-confirmation')
|| setting('registration-restrict');
}
}
View on GitHub (pinned to 18f8469a1c)
Solutions
- No action needed by the user — the account is already confirmed; proceed to log in
- If you are the admin, verify the user's email_confirmed status before resending
- In code, check $user->email_confirmed before calling sendConfirmation
- If the flag is wrongly true (user never got email), set email_confirmed back to false and resend
Example fix
// before
$service->sendConfirmation($user);
// after
if (!$user->email_confirmed) {
$service->sendConfirmation($user);
} Defensive patterns
Strategy: validation
Validate before calling
if ($user->email_confirmed) {
return; // already confirmed, skip sending
} Type guard
function needsConfirmation(\BookStack\Users\User $user): bool {
return $user->email_confirmed === false;
} Try / catch
try {
$emailConfirmationService->sendConfirmation($user);
} catch (\BookStack\Access\Exceptions\ConfirmationEmailException $e) {
// user already confirmed
} Prevention
- Check email_confirmed before any resend action in custom code
- Debounce resend buttons in the UI
- Sync email_confirmed state when importing users
When it happens
Trigger: Calling sendConfirmation($user) (e.g. via the 'resend confirmation' action or admin resend) for a user whose email_confirmed column is already 1/true.
Common situations: User double-clicks the resend button or retries after the email already worked; admin manually resends for a confirmed user; user confirms in another tab then requests again; seeded/imported users already marked confirmed.
Related errors
- auth.email_confirm_send_error
- errors.oidc_no_email_address
- {$exception->getMessage()}
- auth.registrations_disabled
- errors.error_user_exists_different_creds
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/16a2a9d2c2d32a4e.
Report an issue: GitHub.