{"record":{"id":"9b68a25534368eba","repo":"RocketChat/Rocket.Chat","slug":"ldap-login-error","errorCode":"LDAP-login-error","errorMessage":"LDAP Authentication succeeded, but there's already an existing user with provided username [${user.username}] in Mongo.","messagePattern":"LDAP Authentication succeeded, but there's already an existing user with provided username \\[(.+?)\\] in Mongo\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/ldap/Manager.ts","lineNumber":345,"sourceCode":"\t): Promise<void> {\n\t\tlogger.debug('running onLDAPLogin');\n\t\tif (settings.get<boolean>('LDAP_Login_Fallback') && typeof password === 'string' && password.trim() !== '') {\n\t\t\tawait Accounts.setPasswordAsync(user._id, password, { logout: false });\n\t\t}\n\n\t\tawait this.syncUserAvatar(user, ldapUser);\n\t\tawait callbacks.run('onLDAPLogin', { user, ldapUser, isNewUser }, ldap);\n\t}\n\n\tprivate static async loginExistingUser(\n\t\tldap: LDAPConnection,\n\t\tuser: IUser,\n\t\tldapUser: ILDAPEntry,\n\t\tpassword?: string,\n\t): Promise<LDAPLoginResult> {\n\t\tif (user.ldap !== true && settings.get('LDAP_Merge_Existing_Users') !== true) {\n\t\t\tlogger.debug('User exists without \"ldap: true\"');\n\t\t\tthrow new Meteor.Error(\n\t\t\t\t'LDAP-login-error',\n\t\t\t\t`LDAP Authentication succeeded, but there's already an existing user with provided username [${user.username}] in Mongo.`,\n\t\t\t);\n\t\t}\n\n\t\t// If we're merging an ldap user with a local user, then we need to sync the data even if 'update data on login' is off.\n\t\tconst forceUserSync = !user.ldap;\n\n\t\tconst syncData = forceUserSync || (settings.get<boolean>('LDAP_Update_Data_On_Login') ?? true);\n\t\tlogger.debug({ msg: 'Logging user in', syncData });\n\t\tconst updatedUser = (syncData && (await this.syncUserForLogin(ldapUser, user))) || user;\n\n\t\tawait this.onLogin(ldapUser, updatedUser, password, ldap, false);\n\t\treturn {\n\t\t\tuserId: user._id,\n\t\t};\n\t}\n","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/ldap/Manager.ts#L327-L363","documentation":"Thrown by LDAP Manager.loginExistingUser when LDAP authentication succeeded but the matching local account was never marked as an LDAP user (user.ldap !== true) and the setting LDAP_Merge_Existing_Users is not enabled. Rocket.Chat refuses to silently convert a local password account into an LDAP-backed one, so login fails with Meteor.Error code 'LDAP-login-error'.","triggerScenarios":"An employee first signs in via LDAP (SSO) using a username that already exists as a local account created earlier by registration, admin provisioning, or migration; their document lacks ldap: true and Admin -> LDAP -> 'Merge existing users' is off, so loginExistingUser throws after the bind succeeds.","commonSituations":"Companies rolling out LDAP/SAML after running Rocket.Chat with local accounts; provisioning scripts that pre-create accounts without the ldap flag; test users created manually before SSO was enabled; same username in both systems by coincidence.","solutions":["Enable Admin -> LDAP -> Advanced -> 'Merge existing users' (LDAP_Merge_Existing_Users = true) so the existing account is adopted and flagged as ldap on next login","Alternatively rename or delete the conflicting local account so the LDAP user is created fresh","As the affected user, keep using local credentials until an admin resolves the collision"],"exampleFix":"// before — default settings\nLDAP_Merge_Existing_Users = false  // local user 'jane' blocks LDAP login for 'jane'\n\n// after\nAdmin -> LDAP -> Advanced -> Merge existing users = true\n// next LDAP login syncs and flags the account; or rename the local account first","handlingStrategy":"try-catch","validationCode":"// server-side pre-check before enabling LDAP for a workspace with local accounts\nif (settings.get<boolean>('LDAP_Merge_Existing_Users') !== true) {\n  // warn: any username existing as a non-LDAP local account will fail LDAP login\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await ldapLogin(username, password);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'LDAP-login-error') {\n    // LDAP bind succeeded but a local (non-ldap) account owns this username:\n    // enable Admin -> LDAP -> 'Merge existing users', or rename/remove the local account\n  }\n  throw err;\n}","preventionTips":["Enable LDAP_Merge_Existing_Users before announcing SSO login to users who have local accounts","Audit usernames that exist both locally and in LDAP before cutover (users list vs directory export)","Provision pre-existing users with ldap: true when they are known to be directory-backed"],"tags":["ldap","authentication","login","user-conflict"],"backgroundTag":"ldap-existing-user-conflict","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}