BookStackApp/BookStack · error · UserRegistrationException
auth.email_confirm_send_error
Error message
auth.email_confirm_send_error
What it means
This is a UserRegistrationException thrown by BookStack's RegistrationService (registerUser) when the email-confirmation mail cannot be sent to a newly registered user. After creating the account, if email confirmation is required, the service calls EmailConfirmationService::sendConfirmation; any Exception from that call is caught, translated via the 'auth.email_confirm_send_error' language key, and re-thrown as a UserRegistrationException with redirect '/register/confirm'. The user account itself has already been created; only the confirmation email dispatch failed.
Source
Thrown at app/Access/RegistrationService.php:118
// Assign a social account if given
if ($socialAccount) {
$newUser->socialAccounts()->save($socialAccount);
}
Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);
Theme::dispatch(ThemeEvents::AUTH_REGISTER, $authSystem, $newUser);
// Start the email confirmation flow if required
if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
$newUser->save();
try {
$this->emailConfirmationService->sendConfirmation($newUser);
session()->flash('sent-email-confirmation', true);
} catch (Exception $e) {
$message = trans('auth.email_confirm_send_error');
throw new UserRegistrationException($message, '/register/confirm');
}
}
return $newUser;
}
/**
* Ensure that the given email meets any active email domain registration restrictions.
* Throws if restrictions are active and the email does not match an allowed domain.
*
* @throws UserRegistrationException
*/
protected function ensureEmailDomainAllowed(string $userEmail): void
{
$registrationRestrict = setting('registration-restrict');
if (!$registrationRestrict) {
return;View on GitHub (pinned to 18f8469a1c)
Solutions
- Test the mail configuration: run 'php artisan bookstack:send-test-email' (or check the mail settings in .env: MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD, MAIL_ENCRYPTION) and fix credentials/host so sendConfirmation succeeds.
- Verify the account was still created (users table) — if so, the user can log in and you can resend confirmation from the user-profile page instead of re-registering.
- If email confirmation is not needed, disable it ('Require email confirmation' toggle under Settings > Registration) so the sendConfirmation path is skipped.
- In dev, switch MAIL_DRIVER to 'log' so confirmation 'emails' are written to the log and the flow completes without a real mail server.
- Check mail server logs / firewall for rejected connections (port 25 often blocked on cloud hosts); use port 587 with STARTTLS via a relay.
Example fix
// before (.env, broken SMTP) MAIL_HOST=mail.example.com MAIL_USERNAME= MAIL_PASSWORD= // after (.env, working SMTP) MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_USERNAME=no-reply@example.com MAIL_PASSWORD=secret MAIL_ENCRYPTION=tls
Defensive patterns
Strategy: try-catch
Validate before calling
// Before triggering registration (or before resend), verify mail config is usable:
$transportOk = config('mail.mailers.smtp.host') !== null;
// Better: actually probe the transport
catchable_check: try {
Mail::raw('probe', function ($m) { $m->to('probe@example.com')->subject('probe'); });
} catch (\Throwable $e) {
// mail transport misconfigured — fix MAIL_* settings before registering users
} Try / catch
use BookStack\Exceptions\UserRegistrationException;
try {
$user = $registrationService->registerUser($userData, $socialAccount, false);
} catch (UserRegistrationException $e) {
// message is the translated 'auth.email_confirm_send_error'; account may already exist
logger()->warning('Registration confirmation email failed: ' . $e->getMessage());
return redirect($e->getRedirect()); // '/register/confirm'
} Prevention
- Run 'php artisan bookstack:send-test-email' after every mail config change
- Keep MAIL_* env vars in a validated checklist for deployments (host, port, username, password, encryption)
- Use a reliable relay (port 587/STARTTLS) since outbound port 25 is commonly blocked
- Monitor the activity/logs for this exception to detect mail outages before users register
When it happens
Trigger: A user completes the registration form while email confirmation is enabled (confirmationRequired() returns true and the account is not pre-confirmed), the user record is created, and sendConfirmation() throws — typically because the configured mailer (SMTP/mailgun/SES/log driver) fails: SMTP connection refused/auth failure, missing mail env vars (MAIL_HOST, MAIL_USERNAME, etc.), or a mail-driver API error.
Common situations: Self-hosted BookStack instances where SMTP credentials were changed or the mail server is down; Docker deployments missing MAIL_* environment variables; using a mail service whose API key expired; local dev environments with no working mail transport configured (e.g. 'mail' driver on a host without sendmail); firewall blocking outbound port 25/587.
Related errors
- auth.registration_email_domain_invalid
- errors.email_already_confirmed
- errors.path_not_writable
- errors.image_upload_replace_type
- errors.cannot_create_thumbs
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/e4fc2a97e9b3eff7.
Report an issue: GitHub.