{"record":{"id":"58f38015d5e6742c","repo":"RocketChat/Rocket.Chat","slug":"ldap-search-failed","errorCode":null,"errorMessage":"LDAP_search_failed","messagePattern":"LDAP_search_failed","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/ldap.ts","lineNumber":79,"sourceCode":"\t\t\t200: ajv.compile<{ message: string; success: true }>(messageResponseSchema),\n\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t403: validateForbiddenErrorResponse,\n\t\t},\n\t},\n\tasync function action() {\n\t\tif (!this.userId) {\n\t\t\tthrow new Error('error-invalid-user');\n\t\t}\n\n\t\tif (settings.get<boolean>('LDAP_Enable') !== true) {\n\t\t\tthrow new Error('LDAP_disabled');\n\t\t}\n\n\t\ttry {\n\t\t\tawait LDAP.testSearch(this.bodyParams.username);\n\t\t} catch (err) {\n\t\t\tSystemLogger.error({ err });\n\t\t\tthrow new Error('LDAP_search_failed');\n\t\t}\n\n\t\treturn API.v1.success({\n\t\t\tmessage: 'LDAP_User_Found' as const,\n\t\t});\n\t},\n);\n","sourceCodeStart":61,"sourceCodeEnd":87,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/ldap.ts#L61-L87","documentation":"POST /api/v1/ldap.testSearch wraps any failure of Manager.testSearch(username) in Error('LDAP_search_failed') (ldap.ts:79). Manager.testSearch (apps/meteor/server/lib/ldap/Manager.ts:117-133) connects, runs searchByUsername, and throws 'User not found' when the result count is not exactly 1 - so zero matches (wrong username, filter, or Base DN) and ambiguous multi-match filters both map here, as do connect/bind failures. The real cause is logged via the LDAP logger; the API only returns the generic message.","triggerScenarios":"Test username that does not exist in the directory; LDAP_Filter mismatched to schema (e.g. (uid=%s) against Active Directory where the attribute is sAMAccountName); LDAP_BaseDN that excludes the user; bind user lacking search rights; filter broad enough to match multiple entries.","commonSituations":"OpenLDAP defaults used against AD; Base DN not updated after OU restructuring; testing with an email address while the filter matches uid; read-only bind accounts with restricted search scope.","solutions":["Check server logs for the underlying error - 'User not found' vs connect/bind tells you which failure class it is","Verify LDAP_BaseDN actually contains the test user's OU","Match LDAP_Filter to the directory schema: sAMAccountName or userPrincipalName on AD, uid on OpenLDAP","Reproduce with ldapsearch -D <bind> -b <base> '(attr=username)' and require exactly one result"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (typeof username !== 'string' || username.trim() === '') {\n  throw new Error('Provide a non-empty username for ldap.testSearch');\n}\nawait api.post('/api/v1/ldap.testSearch', { username });","typeGuard":null,"tryCatchPattern":"try {\n  await api.post('/api/v1/ldap.testSearch', { username });\n} catch (err) {\n  if (err.response?.body?.error === 'LDAP_search_failed') {\n    // distinguish via server logs: 'User not found' => filter/baseDN problem; bind/connect errors => connectivity\n    hint('Check LDAP_Filter/LDAP_BaseDN against the directory; a passing test must return exactly one match');\n    return;\n  }\n  throw err;\n}","preventionTips":["Validate the filter/baseDN combination with ldapsearch before blaming connectivity - a search must match exactly one entry","Use schema-correct filters (sAMAccountName on AD, uid on OpenLDAP)","Keep the LDAP logger enabled while testing; the API response omits the cause"],"tags":["ldap","search","active-directory","directory"],"backgroundTag":"ldap-search-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}