apache/druid · warning · BasicSecurityAuthenticationException
Unauthorized
Error message
Unauthorized
What it means
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.
Source
Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/validator/MetadataStoreCredentialsValidator.java:87
if (user == null) {
return null;
}
BasicAuthenticatorCredentials credentials = user.getCredentials();
if (credentials == null) {
return null;
}
byte[] recalculatedHash = hashGenerator.getOrComputePasswordHash(
password,
credentials.getSalt(),
credentials.getIterations()
);
if (Arrays.equals(recalculatedHash, credentials.getHash())) {
return new AuthenticationResult(username, authorizerName, authenticatorName, null);
} else {
LOG.debug("Password incorrect for metadata store user %s", username);
throw new BasicSecurityAuthenticationException(Access.DEFAULT_ERROR_MESSAGE);
}
}
}
View on GitHub (pinned to 9b90983fd2)
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
Example fix
// before
// auth returns Unauthorized after password rotation on another node
// after
// ensure coordinators propagated the update; then update client credentials
curl -X POST coordinator/druid-ext/basic-security/authentication/basic/users/alice/credentials -d '{...}' Defensive patterns
Strategy: validation
Validate before calling
// confirm the user has credentials set before attempting authentication
Response r = client.getUser(authenticatorName, username);
if (r.getStatus() == 200 && credentialsMissing(r)) { throw new IllegalStateException("credentials not set"); } Try / catch
try {
AuthenticationResult result = validator.validateCredentials(username, password);
} catch (BasicSecurityAuthenticationException e) {
// 'Unauthorized': hash mismatch — wrong password or stale cache
promptForPasswordReset(username);
} Prevention
- 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
When it happens
Trigger: Calling validateCredentials (MetadataStoreCredentialsValidator) with a password whose PBKDF2 hash differs from the stored BasicAuthenticatorCredentials hash for that user.
Common situations: 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.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Could not delete user[%s] due to concurrent update contentio
- Unauthorized
- The gRPC query server requires either a Basic or Anonymous a
- Failed to authenticate to schema registry for Avro schema id
- Either set 'key' or 'sharedAccessStorageToken' or 'useAzureC
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/25cd8f1dda05a11f.
Report an issue: GitHub.