{"record":{"id":"25cd8f1dda05a11f","repo":"apache/druid","slug":"unauthorized-25cd8f","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/MetadataStoreCredentialsValidator.java","lineNumber":87,"sourceCode":"    if (user == null) {\n      return null;\n    }\n    BasicAuthenticatorCredentials credentials = user.getCredentials();\n    if (credentials == null) {\n      return null;\n    }\n\n    byte[] recalculatedHash = hashGenerator.getOrComputePasswordHash(\n        password,\n        credentials.getSalt(),\n        credentials.getIterations()\n    );\n\n    if (Arrays.equals(recalculatedHash, credentials.getHash())) {\n      return new AuthenticationResult(username, authorizerName, authenticatorName, null);\n    } else {\n      LOG.debug(\"Password incorrect for metadata store user %s\", username);\n      throw new BasicSecurityAuthenticationException(Access.DEFAULT_ERROR_MESSAGE);\n    }\n  }\n}\n","sourceCodeStart":69,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/validator/MetadataStoreCredentialsValidator.java#L69-L91","documentation":"Thrown as BasicSecurityAuthenticationException when the recalculated salted hash of the supplied password does not match the stored credentials hash in the metadata store. It surfaces as the generic 'Unauthorized' message to avoid leaking information. This is the standard wrong-password failure for metadata-store-backed basic authentication.","triggerScenarios":"Calling validateCredentials (MetadataStoreCredentialsValidator) with a password whose PBKDF2 hash differs from the stored BasicAuthenticatorCredentials hash for that user.","commonSituations":"User typed the wrong password; credentials were never set for the user or were rotated on another node before this node refreshed its cache; client sending stale credentials after a password update; user exists but with null/empty credentials in a partially completed provisioning.","solutions":["Re-set the user's credentials via the coordinator credentials API and confirm they propagate","Wait for/force the credentials cache to refresh on all nodes (or restart to pick up the current user map)","Verify the client is sending the current password (no stale cached credentials)","Check that provisioning completed: user created AND credentials set"],"exampleFix":"// before\n// auth returns Unauthorized after password rotation on another node\n// after\n// ensure coordinators propagated the update; then update client credentials\ncurl -X POST coordinator/druid-ext/basic-security/authentication/basic/users/alice/credentials -d '{...}'","handlingStrategy":"validation","validationCode":"// confirm the user has credentials set before attempting authentication\nResponse r = client.getUser(authenticatorName, username);\nif (r.getStatus() == 200 && credentialsMissing(r)) { throw new IllegalStateException(\"credentials not set\"); }","typeGuard":null,"tryCatchPattern":"try {\n  AuthenticationResult result = validator.validateCredentials(username, password);\n} catch (BasicSecurityAuthenticationException e) {\n  // 'Unauthorized': hash mismatch — wrong password or stale cache\n  promptForPasswordReset(username);\n}","preventionTips":["Rotate credentials via the coordinator API and let caches refresh before clients retry","Ensure provisioning completes both create-user and set-credentials steps","Avoid sending stale cached credentials from clients after a password change"],"tags":["authentication","bad-credentials","basic-security","metadata-store"],"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"}