{"record":{"id":"84b2d87b58d27145","repo":"SonarSource/sonarqube","slug":"unable-to-open-ldap-connection","errorCode":null,"errorMessage":"Unable to open LDAP connection","messagePattern":"Unable to open LDAP connection","errorType":"exception","errorClass":"LdapException","httpStatus":null,"severity":"error","filePath":"server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapContextFactory.java","lineNumber":230,"sourceCode":"  public boolean isGssapi() {\n    return AUTH_METHOD_GSSAPI.equals(authentication);\n  }\n\n  /**\n   * Tests connection.\n   *\n   * @throws LdapException if unable to open connection\n   */\n  public void testConnection() {\n    if (StringUtils.isBlank(username) && isSasl()) {\n      throw new IllegalArgumentException(\"When using SASL - property ldap.bindDn is required\");\n    }\n    try {\n      createBindContext();\n      LOG.info(\"Test LDAP connection on {}: OK\", providerUrl);\n    } catch (NamingException e) {\n      LOG.info(\"Test LDAP connection: FAIL\");\n      throw new LdapException(\"Unable to open LDAP connection\", e);\n    }\n  }\n\n  public String getProviderUrl() {\n    return providerUrl;\n  }\n\n  public String getReferral() {\n    return referral;\n  }\n\n  private static String getReferralsMode(org.sonar.api.config.Configuration config, String followReferralsSettingKey) {\n    // By default follow referrals\n    return config.getBoolean(followReferralsSettingKey).orElse(true) ? REFERRALS_FOLLOW_MODE : REFERRALS_IGNORE_MODE;\n  }\n\n  @Override\n  public String toString() {","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapContextFactory.java#L212-L248","documentation":"testConnection attempts createBindContext() and, if the bind fails with a NamingException, logs 'Test LDAP connection: FAIL' and rethrows as LdapException 'Unable to open LDAP connection' with the original exception as cause. It is the health-check failure signal for an LDAP endpoint — the library could not establish/bind a directory context.","triggerScenarios":"Calling testConnection when createBindContext() throws — wrong ldap.url host/port, network unreachable, bind credentials rejected (AuthenticationException), or TLS handshake failure on ldaps://.","commonSituations":"LDAP server down or firewall blocking 389/636; expired bind password; TLS certificate not in truststore; DNS resolution failure for the LDAP host; invalid URL scheme in ldap.url.","solutions":["Inspect the cause (NamingException) logged at info/debug to distinguish connectivity vs authentication vs TLS failure.","Verify network reachability: telnet/nc to the ldap host and port.","Validate bind credentials with ldapsearch using the same bindDn/bindPassword.","For ldaps://, import the server certificate into the JVM truststore."],"exampleFix":"// before: wrong port / unreachable\nsonar.authenticator.ldap.url: ldap://ldap.example.com:10389\n// after: correct endpoint\nsonar.authenticator.ldap.url: ldap://ldap.example.com:389","handlingStrategy":"retry","validationCode":"// pre-flight connectivity check before triggering LDAP operations\ntry (Socket s = new Socket()) {\n  s.connect(new InetSocketAddress(host, port), 3000); // host/port parsed from ldap.url\n}","typeGuard":null,"tryCatchPattern":"try {\n  contextFactory.testConnection();\n} catch (LdapException e) {\n  if (e.getCause() instanceof CommunicationException) {\n    // retry with backoff; likely transient network issue\n  } else if (e.getCause() instanceof AuthenticationException) {\n    // fix bindDn/bindPassword — do not retry blindly\n  }\n}","preventionTips":["Run testConnection-equivalent ldapsearch checks in deployment health checks.","Keep LDAP service account passwords in rotation monitoring.","Use IP/DNS that resolves from the SonarQube host, not just yours."],"tags":["ldap","connection","bind-failure","network"],"backgroundTag":"connection-refused","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}