BookStackApp/BookStack · error · UserRegistrationException

errors.error_user_exists_different_creds

Error message

errors.error_user_exists_different_creds

What it means

During registerUser(), after domain checks, BookStack checks whether a user with the given email already exists ($this->userRepo->getByEmail($userEmail)). If so, it throws UserRegistrationException with 'errors.error_user_exists_different_creds' (parameterized with the email), because auto-creating a duplicate account is unsafe — the email belongs to an account using different credentials.

Source

Thrown at app/Access/RegistrationService.php:87

    }

    /**
     * The registrations flow for all users.
     *
     * @throws UserRegistrationException
     */
    public function registerUser(array $userData, ?SocialAccount $socialAccount = null, bool $emailConfirmed = false): User
    {
        $userEmail = $userData['email'];
        $authSystem = $socialAccount ? $socialAccount->driver : auth()->getDefaultDriver();

        // Email restriction
        $this->ensureEmailDomainAllowed($userEmail);

        // Ensure the user does not already exist
        $alreadyUser = !is_null($this->userRepo->getByEmail($userEmail));
        if ($alreadyUser) {
            throw new UserRegistrationException(trans('errors.error_user_exists_different_creds', ['email' => $userEmail]), '/login');
        }

        /** @var ?bool $shouldRegister */
        $shouldRegister = Theme::dispatch(ThemeEvents::AUTH_PRE_REGISTER, $authSystem, $userData);
        if ($shouldRegister === false) {
            throw new UserRegistrationException(trans('errors.auth_pre_register_theme_prevention'), '/login');
        }

        // Create the user
        $newUser = $this->userRepo->createWithoutActivity($userData, $emailConfirmed);
        $newUser->attachDefaultRole();

        // Assign a social account if given
        if ($socialAccount) {
            $newUser->socialAccounts()->save($socialAccount);
        }

        Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Match the external identity to the existing user: set the user's external_auth_id / system name to the incoming externalId (admin edit or SQL), or log in once via the original method and link accounts
  2. If the existing account is a duplicate/unused, rename or delete it so the external login can register cleanly
  3. Ensure your IdP issues stable external ids so findOrRegister matches by id instead of email
  4. Check the email domain/claims config isn't mapping two distinct external users to one email

Example fix

-- before: existing local user with no external id
-- after: link external id so login matches the existing account
UPDATE users SET external_auth_id='<idp-sub-value>' WHERE email='user@example.com';
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect the conflict before registration:
$existing = $userRepo->getByEmail($incomingEmail);
if ($existing !== null && $existing->external_auth_id !== $incomingExternalId) {
    // email taken by different credentials — link accounts or resolve manually
}

Try / catch

try {
    auth()->attemptOidcLogin();
} catch (BookStack\Access\Oidc\OidcException $e) {
    if (str_contains($e->getMessage(), 'error_user_exists_different_creds') || str_contains($e->getMessage(), 'already')) {
        return redirect('/login')->withErrors(['email' => 'An account with this email exists; sign in with the original method or ask an admin to link accounts']);
    }
    throw $e;
}

Prevention

When it happens

Trigger: registerUser() is invoked via findOrRegister() during OIDC (or similar external) login; the external identity's email matches an existing BookStack user that was registered under a different auth system (e.g. local password, or different IdP), so no account match by external id exists.

Common situations: User previously signed up locally with the same email then tries to log in via OIDC/SAML/LDAP; email changed at the IdP to collide with an existing account; migrating between auth systems without unifying accounts; duplicate emails across IdPs.

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/097711bb2489b153. Report an issue: GitHub.