{"record":{"id":"2011429e5b6ee995","repo":"prestodb/presto","slug":"authentication-error","errorCode":null,"errorMessage":"Authentication error","messagePattern":"Authentication error","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"presto-password-authenticators/src/main/java/com/facebook/presto/password/ldap/LdapAuthenticator.java","lineNumber":119,"sourceCode":"\n    private Principal authenticate(String user, String password)\n    {\n        Map<String, String> environment = createEnvironment(user, password);\n        DirContext context = null;\n        try {\n            context = createDirContext(environment);\n            checkForGroupMembership(user, context);\n\n            log.debug(\"Authentication successful for user [%s]\", user);\n            return new BasicPrincipal(user);\n        }\n        catch (AuthenticationException e) {\n            log.debug(\"Authentication failed for user [%s]: %s\", user, e.getMessage());\n            throw new AccessDeniedException(\"Invalid credentials\");\n        }\n        catch (NamingException e) {\n            log.debug(e, \"Authentication error for user [%s]\", user);\n            throw new RuntimeException(\"Authentication error\");\n        }\n        finally {\n            if (context != null) {\n                closeContext(context);\n            }\n        }\n    }\n\n    private Map<String, String> createEnvironment(String user, String password)\n    {\n        return ImmutableMap.<String, String>builder()\n                .putAll(basicEnvironment)\n                .put(SECURITY_AUTHENTICATION, \"simple\")\n                .put(SECURITY_PRINCIPAL, createPrincipal(user))\n                .put(SECURITY_CREDENTIALS, password)\n                .build();\n    }\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-password-authenticators/src/main/java/com/facebook/presto/password/ldap/LdapAuthenticator.java#L101-L137","documentation":"LdapAuthenticator.authenticate catches javax.naming.NamingException (any non-authentication LDAP failure: connection refused, TLS handshake failure, DNS failure, timeout, malformed DN) and rethrows a generic RuntimeException(\"Authentication error\"). Unlike AuthenticationException, this means the LDAP directory could not be reached or queried at all, not that the credentials were wrong.","triggerScenarios":"During authenticate(), creating the InitialLdapContext or performing the bind throws a NamingException other than AuthenticationException: LDAP host unreachable, wrong port, TLS/certificate failure, or InvalidNameException from a malformed DN built from the username.","commonSituations":"LDAP hostname/port wrong or firewall blocking; LDAPS certificate not in the coordinator truststore; ldap.url uses ldaps:// with misconfigured TLS; username characters yielding an invalid DN; LDAP server down during rolling restart.","solutions":["Check connectivity from the coordinator: test the ldap.url host/port (nc -vz ldap.example.com 636 or ldapsearch)","Fix TLS trust: import the LDAP server certificate chain into the coordinator truststore and verify the ldaps:// URL","Validate that the user-bind-pattern yields a well-formed DN for the attempted username (escape special characters)","Check LDAP server availability/logs for an outage and retry once the directory is reachable"],"exampleFix":"// before\npresto.ldap.url=ldaps://ldap.internal:636  // cert not trusted -> NamingException\n// after\n# keytool -importcert -file ldap.crt -keystore truststore.jks\npresto.ldap.url=ldaps://ldap.internal:636\n# with -Djavax.net.ssl.trustStore=/etc/presto/truststore.jks","handlingStrategy":"try-catch","validationCode":"// Pre-flight LDAP reachability check:\ntry (Socket s = new Socket()) {\n    s.connect(new InetSocketAddress(\"ldap.example.com\", 636), 3000); // throws if unreachable\n}","typeGuard":null,"tryCatchPattern":"try {\n    return ldapAuthenticator.authenticate(user, password);\n} catch (RuntimeException e) {\n    if (\"Authentication error\".equals(e.getMessage())) { // NamingException path\n        // LDAP infra problem, not bad credentials: fail with 503, not 401\n        throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);\n    }\n    throw e;\n}","preventionTips":["Import the LDAP server certificate chain into the coordinator truststore and verify with openssl s_client","Add a coordinator health check that performs a lightweight LDAP bind/starttls probe","Use redundant LDAP URLs so a single server outage does not break authentication","Differentiate 401 (AccessDenied) vs 503 (Runtime 'Authentication error') in handling and monitoring"],"tags":["ldap","network","naming-exception","tls"],"backgroundTag":"ldap-connection-error","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}