prestodb/presto · warning · AccessDeniedException
Invalid credentials
Error message
Invalid credentials
What it means
LdapAuthenticator.authenticate catches javax.naming.AuthenticationException from the LDAP bind and rethrows it as AccessDeniedException("Invalid credentials"). This means the LDAP server explicitly rejected the bind for the supplied user DN/password: a genuine authentication rejection by the directory, surfaced to the client as invalid credentials.
Source
Thrown at presto-password-authenticators/src/main/java/com/facebook/presto/password/ldap/LdapAuthenticator.java:115
private Principal authenticate(Credentials credentials)
{
return authenticate(credentials.getUser(), credentials.getPassword());
}
private Principal authenticate(String user, String password)
{
Map<String, String> environment = createEnvironment(user, password);
DirContext context = null;
try {
context = createDirContext(environment);
checkForGroupMembership(user, context);
log.debug("Authentication successful for user [%s]", user);
return new BasicPrincipal(user);
}
catch (AuthenticationException e) {
log.debug("Authentication failed for user [%s]: %s", user, e.getMessage());
throw new AccessDeniedException("Invalid credentials");
}
catch (NamingException e) {
log.debug(e, "Authentication error for user [%s]", user);
throw new RuntimeException("Authentication error");
}
finally {
if (context != null) {
closeContext(context);
}
}
}
private Map<String, String> createEnvironment(String user, String password)
{
return ImmutableMap.<String, String>builder()
.putAll(basicEnvironment)
.put(SECURITY_AUTHENTICATION, "simple")
.put(SECURITY_PRINCIPAL, createPrincipal(user))View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the client's password by binding manually (ldapwhoami -x -H ldaps://... -D <userDn> -W)
- Check the user-bind-pattern produces the correct DN; test the exact DN with ldapsearch
- Confirm the user account is active (not locked/expired) and under the expected base DN
- Enable debug logging to see the user DN used and the server's rejection reason
Example fix
// before
presto.ldap.user-bind-pattern=${USER}@example.com // wrong form for this directory
// after
presto.ldap.user-bind-pattern=uid=${USER},ou=people,dc=example,dc=com Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the bind works before pointing the coordinator at it: // ldapwhoami -x -H ldaps://ldap.example.com:636 -D 'uid=alice,ou=people,dc=example,dc=com' -W
Try / catch
try {
return ldapAuthenticator.authenticate(user, password);
} catch (AccessDeniedException e) {
auditLog.warn("LDAP bind rejected for user {}", user);
throw new WebApplicationException(Status.UNAUTHORIZED);
} Prevention
- Test the exact DN from the user-bind-pattern with ldapwhoami before deploying config changes
- Keep client LDAP passwords in sync via the same secrets pipeline as the directory
- Monitor user account lockout/expiry in the directory
- Escape/sanitize usernames used in DN construction
When it happens
Trigger: A client authenticates; the authenticator binds to the LDAP server as the DN built from the user-bind-pattern with the given password; the server returns AuthenticationException (LDAP code 49, invalid credentials).
Common situations: Wrong password on the client; user DN template mismatch so the bind DN is wrong; user missing, disabled, or locked in LDAP; expired password; wrong base DN or replica; special characters in the username breaking DN construction.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid credentials
- User [%s] not a member of the authorized group
- PINOT_UNAUTHENTICATED_EXCEPTION
- UNEXPECTED_ACCUMULO_ERROR
- UNEXPECTED_ACCUMULO_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/3e00212aba1207d3.
Report an issue: GitHub.