{"record":{"id":"bb74febc98ad5fa5","repo":"apache/druid","slug":"unauthorized-bb74fe","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"BasicSecurityAuthenticationException","httpStatus":401,"severity":"warning","filePath":"extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/validator/LDAPCredentialsValidator.java","lineNumber":206,"sourceCode":"          try {\n            dirContext.close();\n          }\n          catch (Exception ignored) {\n            // ignored\n          }\n        }\n      }\n      catch (NamingException e) {\n        LOG.error(e, \"Exception during user lookup\");\n        return null;\n      }\n      finally {\n        Thread.currentThread().setContextClassLoader(currentClassLoader);\n      }\n\n      if (!validatePassword(this.ldapConfig, userDn, password)) {\n        LOG.debug(\"Password incorrect for LDAP user %s\", username);\n        throw new BasicSecurityAuthenticationException(Access.DEFAULT_ERROR_MESSAGE);\n      }\n\n      if (this.ldapConfig.isGroupSearchConfigured() && !hasMemberOfAttribute(userResult)) {\n        enrichWithGroupSearch(userResult);\n      }\n\n      byte[] salt = BasicAuthUtils.generateSalt();\n      byte[] hash = hashGenerator.getOrComputePasswordHash(password, salt, this.ldapConfig.getCredentialIterations());\n      LdapUserPrincipal newPrincipal = new LdapUserPrincipal(\n          username,\n          new BasicAuthenticatorCredentials(salt, hash, this.ldapConfig.getCredentialIterations()),\n          userResult\n      );\n\n      this.cache.put(username, newPrincipal);\n      contextMap.put(BasicAuthUtils.SEARCH_RESULT_CONTEXT_KEY, userResult);\n    }\n    return new AuthenticationResult(username, authorizerName, authenticatorName, contextMap);","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/validator/LDAPCredentialsValidator.java#L188-L224","documentation":"Thrown as BasicSecurityAuthenticationException when the supplied password fails LDAP binding/validation for the user's DN (validatePassword returned false). It maps to the generic 'Unauthorized' message (Access.DEFAULT_ERROR_MESSAGE) so no credential detail leaks. The authentication result is a failure delivered to the authenticator chain.","triggerScenarios":"Calling validateCredentials (via the basic LDAP authenticator during HTTP authentication) with a password that does not match the LDAP directory entry for the resolved user DN.","commonSituations":"Wrong password typed by the user or sent by a misconfigured client; LDAP bind account/config (url, baseDn, userSearch) resolving to the wrong DN; password recently changed in LDAP and cached credentials still in use; case or whitespace issues in the supplied credentials.","solutions":["Verify the username/password combination directly against the LDAP directory (e.g. ldapwhoami)","Check the LDAP authenticator config (url, baseDn, userSearch, filters) resolves the correct user DN","Ensure clients are sending updated credentials after password changes","Check coordinator/overlord logs (debug level) for 'Password incorrect for LDAP user' to distinguish wrong password from config errors"],"exampleFix":"// before\n// auth fails with generic Unauthorized, no diagnostics\n// after\n// enable debug logging to confirm wrong-password vs DN-resolution issues\nlog4j.logger.org.apache.druid.security.basic.authentication.validator.LDAPCredentialsValidator=DEBUG","handlingStrategy":"try-catch","validationCode":"// cannot pre-validate a password, but verify LDAP connectivity/config first\n// ensure the authenticator config resolves the user DN, e.g. run ldapwhoami with the same bind params","typeGuard":null,"tryCatchPattern":"try {\n  AuthenticationResult result = authenticator.authenticate(request, username, password);\n} catch (BasicSecurityAuthenticationException e) {\n  // Access.DEFAULT_ERROR_MESSAGE 'Unauthorized': wrong password or bad LDAP config\n  auditLog.warn(\"LDAP auth failed for user \" + username);\n}","preventionTips":["Test credentials directly against LDAP with ldapwhoami/ldapsearch","Double-check url, baseDn, userSearch settings in the LDAP authenticator config","Enable debug logging on LDAPCredentialsValidator to distinguish wrong password from DN-resolution problems"],"tags":["ldap","authentication","bad-credentials"],"backgroundTag":"authentication-required","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}