{"record":{"id":"097711bb2489b153","repo":"BookStackApp/BookStack","slug":"errors-error-user-exists-different-creds","errorCode":null,"errorMessage":"errors.error_user_exists_different_creds","messagePattern":"errors\\.error_user_exists_different_creds","errorType":"exception","errorClass":"UserRegistrationException","httpStatus":null,"severity":"error","filePath":"app/Access/RegistrationService.php","lineNumber":87,"sourceCode":"    }\n\n    /**\n     * The registrations flow for all users.\n     *\n     * @throws UserRegistrationException\n     */\n    public function registerUser(array $userData, ?SocialAccount $socialAccount = null, bool $emailConfirmed = false): User\n    {\n        $userEmail = $userData['email'];\n        $authSystem = $socialAccount ? $socialAccount->driver : auth()->getDefaultDriver();\n\n        // Email restriction\n        $this->ensureEmailDomainAllowed($userEmail);\n\n        // Ensure the user does not already exist\n        $alreadyUser = !is_null($this->userRepo->getByEmail($userEmail));\n        if ($alreadyUser) {\n            throw new UserRegistrationException(trans('errors.error_user_exists_different_creds', ['email' => $userEmail]), '/login');\n        }\n\n        /** @var ?bool $shouldRegister */\n        $shouldRegister = Theme::dispatch(ThemeEvents::AUTH_PRE_REGISTER, $authSystem, $userData);\n        if ($shouldRegister === false) {\n            throw new UserRegistrationException(trans('errors.auth_pre_register_theme_prevention'), '/login');\n        }\n\n        // Create the user\n        $newUser = $this->userRepo->createWithoutActivity($userData, $emailConfirmed);\n        $newUser->attachDefaultRole();\n\n        // Assign a social account if given\n        if ($socialAccount) {\n            $newUser->socialAccounts()->save($socialAccount);\n        }\n\n        Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Access/RegistrationService.php#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","If the existing account is a duplicate/unused, rename or delete it so the external login can register cleanly","Ensure your IdP issues stable external ids so findOrRegister matches by id instead of email","Check the email domain/claims config isn't mapping two distinct external users to one email"],"exampleFix":"-- before: existing local user with no external id\n-- after: link external id so login matches the existing account\nUPDATE users SET external_auth_id='<idp-sub-value>' WHERE email='user@example.com';","handlingStrategy":"try-catch","validationCode":"// Detect the conflict before registration:\n$existing = $userRepo->getByEmail($incomingEmail);\nif ($existing !== null && $existing->external_auth_id !== $incomingExternalId) {\n    // email taken by different credentials — link accounts or resolve manually\n}","typeGuard":null,"tryCatchPattern":"try {\n    auth()->attemptOidcLogin();\n} catch (BookStack\\Access\\Oidc\\OidcException $e) {\n    if (str_contains($e->getMessage(), 'error_user_exists_different_creds') || str_contains($e->getMessage(), 'already')) {\n        return redirect('/login')->withErrors(['email' => 'An account with this email exists; sign in with the original method or ask an admin to link accounts']);\n    }\n    throw $e;\n}","preventionTips":["Keep external_auth_id stable and populated so matching works by id","Migrate accounts explicitly (set external_auth_id) when switching auth systems","Prevent duplicate emails across IdPs with provisioning checks","Document an admin runbook for resolving email conflicts"],"tags":["registration","account-conflict","oidc"],"backgroundTag":"email-already-registered","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}