Fix LDAP Working but LDAPS Failing in 389 Directory Server

Fix LDAP works but LDAPS fails in 389 Directory Server by checking port 636, the TLS handshake, client CA trust, hostname matching, server certificates, and access logs.

Published

Updated

Read time 13 min read

Reviewed byDeepak Prasad

Fix LDAP works but LDAPS fails in 389 Directory Server — port 636 listener, certificate trust, hostname validation, and TLS handshake troubleshooting
Tested on Rocky Linux 10.2 (Red Quartz)
Package 389-ds-base 3.2.0-8.el10_2
Applies to RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora
Privilege sudo or root
Scope Fix LDAP works but LDAPS fails: port 636, TLS handshake, trust, hostname matching, and certificates. Does not cover unrelated LDAP error codes.
Related guides Install 389 Directory Server
389 DS TLS
Certificate management
dsconf commands
Fix LDAP invalid credentials error 49

LDAP works but LDAPS fails is a common production pattern: directory data is reachable over ldap:// on port 389, while applications, scripts, or ldapsearch against ldaps:// on port 636 time out, refuse the connection, or exit before bind with a generic client error. SSSD, Apache, replication tools, and backup jobs often show the same split when only the secure URI was changed.

Typical LDAPS failures look like this on the client:

text
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

With debug output enabled, the same session often reveals the underlying TLS problem:

output
TLS certificate verification: Error, self-signed certificate in certificate chain
TLS: can't connect: error:0A000086:SSL routines::certificate verify failed (self-signed certificate in certificate chain).
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

Plain LDAP on the same client can still return directory data:

output
dn:
namingContexts: dc=example,dc=com

A failed TLS handshake may never reach the LDAP bind stage, so the access log on the server can show no bind attempt for the failed client session. Separate port or listener failures from certificate-validation failures from LDAP bind failures after TLS succeeds.

Use the diagnosis table below to jump to the fix that matches your situation. Initial TLS setup, certificate renewal, and cipher policy stay in the linked chapters.

IMPORTANT
This article covers LDAPS connection and TLS troubleshooting when unencrypted LDAP still works. It does not cover initial TLS installation, client-certificate authentication, or LDAP result codes that appear only after a successful bind.

Examples use instance ldap1 on ldap1.example.com with LDAP port 389 and LDAPS port 636, suffix dc=example,dc=com, and server address 192.0.2.10 in DNS examples. Use the same DNS hostname in client URIs, certificates, and firewall rules.

Keep server-side and client-side paths separate:

Location Path
Server NSS database /etc/dirsrv/slapd-ldap1/
CA exported on the server /tmp/ds-ca.crt
CA installed on the client /etc/pki/ca-trust/source/anchors/ds-ca.crt

Export the CA on the directory server, transfer /tmp/ds-ca.crt to the failing client, then install it with update-ca-trust or LDAPTLS_CACERT. Commands that use -y /root/dm.pw run on the machine where that password file exists; a server-side credential file is not present on remote SSSD, Apache, or application hosts unless you create it there deliberately.


Causes and fixes at a glance

Symptom or test result Likely cause Fix
LDAP works, LDAPS connection refused Port 636 not listening or blocked Check the LDAPS listener
LDAP works, LDAPS certificate error in -d 1 output Client does not trust the issuing CA Fix client CA trust
LDAP URI uses an IP but certificate lists DNS names only Hostname or SAN mismatch Fix client CA trust
StartTLS works, LDAPS fails Dedicated port 636 or listener issue Check the LDAPS listener
LDAPS works locally but not remotely Firewall, routing, DNS, or load balancer Check network access and TLS compatibility
LDAPS works only through localhost Secure listener bound to loopback ss and nsslapd-securelistenhost
openssl verifies with CA file but ldapsearch fails LDAP client CA configuration Fix client CA trust
No peer certificate returned Server did not complete TLS negotiation Test the TLS handshake
Certificate expired Server presents an expired certificate Check the server certificate database
Old client cannot connect TLS version or cipher mismatch Check network access and TLS compatibility
TLS succeeds but bind returns error 49 Credentials are incorrect Fix LDAP invalid credentials error 49
TLS succeeds but operation returns error 50 ACI denies the operation Fix LDAP insufficient access error 50

Classify the failure with LDAP, LDAPS, and StartTLS

Run anonymous Root DSE searches from the client that fails in production. These commands test transport and trust without sending bind credentials over plain LDAP.

Plain LDAP on port 389:

bash
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -b "" -s base "(objectClass=*)" namingContexts

Sample output when LDAP transport is healthy:

output
dn:
namingContexts: dc=example,dc=com

LDAPS on port 636 without a trusted CA on the client often fails before any LDAP result is returned:

bash
ldapsearch -LLL -x -H ldaps://ldap1.example.com:636 -b "" -s base "(objectClass=*)" namingContexts

Sample output:

output
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

After you install the CA on the client, retry LDAPS with the client-side path:

bash
LDAPTLS_CACERT=/etc/pki/ca-trust/source/anchors/ds-ca.crt ldapsearch -LLL -x -H ldaps://ldap1.example.com:636 -b "" -s base "(objectClass=*)" namingContexts

Sample output when LDAPS transport and trust are configured correctly:

output
dn:
namingContexts: dc=example,dc=com

StartTLS on port 389 isolates whether TLS works on the shared LDAP listener. Use the same client-side CA path:

bash
LDAPTLS_CACERT=/etc/pki/ca-trust/source/anchors/ds-ca.crt ldapsearch -LLL -x -ZZ -H ldap://ldap1.example.com:389 -b "" -s base "(objectClass=*)" namingContexts

Sample output when StartTLS and trust are configured correctly:

output
dn:
namingContexts: dc=example,dc=com
Result Likely direction
LDAP works, LDAPS connection refused Port 636 is not listening or is blocked
LDAP works, LDAPS certificate error in debug output Client trust, certificate chain, or hostname problem
StartTLS works, LDAPS fails Dedicated LDAPS listener, port 636, listen address, or firewall; check ss, nsslapd-securelistenhost, and firewall rules
LDAPS works locally but not remotely Firewall, routing, DNS, or load balancer
openssl succeeds with -CAfile but ldapsearch fails LDAP client CA configuration
All TLS connections fail Server certificate or TLS configuration

When LDAPS fails with -1, add debug output before you change server certificates:

bash
ldapsearch -d1 -x -H ldaps://ldap1.example.com:636 -b "" -s base

The TLS trace lines above the -1 result identify verification failure versus an unreachable port.

After LDAPS transport succeeds, test authentication separately on the same client:

bash
LDAPTLS_CACERT=/etc/pki/ca-trust/source/anchors/ds-ca.crt ldapwhoami -x -H ldaps://ldap1.example.com:636 -D "cn=Directory Manager" -y /root/dm.pw

Sample output:

output
dn: cn=directory manager

A transport success followed by error 49 here is a credential problem, not an LDAPS listener problem.


Check the LDAPS listener

Confirm the instance is running and TLS security is enabled:

bash
dsctl ldap1 status

Sample output:

output
Instance "ldap1" is running
bash
dsconf ldap1 security get

Sample output (trimmed):

output
nsslapd-security: on
nsslapd-secureport: 636
sslversionmin: TLS1.2
sslversionmax: TLS1.3
bash
dsconf ldap1 config get nsslapd-security nsslapd-secureport nsslapd-securelistenhost

Sample output (trimmed):

output
nsslapd-security: on
nsslapd-secureport: 636
nsslapd-securelistenhost:

An empty nsslapd-securelistenhost means the secure listener uses the default bind address. When set to a specific hostname or address, LDAPS accepts connections only on that interface.

bash
dsconf ldap1 security rsa get

Sample output (trimmed):

output
nssslpersonalityssl: Server-Cert
nsssltoken: internal (software)

This shows which NSS nickname the running RSA TLS configuration presents. A certificate can exist in the database under another name but still not be selected for LDAPS until it is configured here.

Inspect listening ports on the directory server:

bash
sudo ss -ltnp | grep -E ':389|:636'

Sample output:

output
LISTEN 0      128                *:636              *:*    users:(("ns-slapd",pid=17960,fd=9))
LISTEN 0      128                *:389              *:*    users:(("ns-slapd",pid=17960,fd=8))

Read the local address column:

ss local address Meaning
*:636 Listening on all interfaces
192.0.2.10:636 Listening on one server interface
127.0.0.1:636 Local connections only

Port 636 with ns-slapd confirms the LDAPS listener is active. If port 636 is absent, verify nsslapd-security and nsslapd-secureport, check the errors log for certificate loading failures, and confirm no other service owns the port. A locally working LDAPS session combined with remote failure can be a listen-address problem even when the firewall is open. Complete initial listener and certificate setup is in configure TLS in 389 Directory Server.


Test the TLS handshake and certificate

Test the TCP and TLS layer independently of the LDAP client:

bash
openssl s_client -connect ldap1.example.com:636 -servername ldap1.example.com -showcerts </dev/null

Sample output (trimmed):

output
depth=1 C=AU, ST=Queensland, L=389ds, O=testing, CN=ssca.389ds.example.com
verify error:num=19:self-signed certificate in certificate chain
CONNECTED(00000005)
Certificate chain
 0 s:CN=ldap1.example.com
   i:CN=ssca.389ds.example.com

CONNECTED confirms that TCP port 636 accepted the connection. A presented peer certificate and negotiated protocol or cipher show that TLS progressed. A verification error still means the client does not trust or cannot validate the server identity. openssl s_client normally continues after certificate-verification errors unless you pass -verify_return_error. Use -CAfile, -verify_hostname, and -verify_return_error for a conclusive validation test.

When summarizing this initial untrusted probe, distinguish:

Observation What it proves
CONNECTED TCP reachable
Protocol and cipher lines TLS negotiated
Certificate chain section Server certificate presented
verify error or non-zero Verify return code Trust or identity validation failed

Inspect subject, issuer, validity, and Subject Alternative Names:

bash
openssl s_client -connect ldap1.example.com:636 -servername ldap1.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

Sample output:

output
subject=C=AU, ST=Queensland, L=389ds, O=testing, GN=dfba1287-caca-47e5-a406-98347d7c0e30, CN=ldap1.example.com
issuer=C=AU, ST=Queensland, L=389ds, O=testing, CN=ssca.389ds.example.com
notBefore=Jul 22 01:18:03 2026 GMT
notAfter=Jul 22 01:18:03 2028 GMT
X509v3 Subject Alternative Name:
    DNS:ldap1.example.com

Use a URI hostname present in the certificate SAN. Modern deployments should issue SAN-bearing certificates rather than relying on legacy CN fallback behavior. OpenLDAP also exposes TLS_REQSAN policy levels, with stricter modes rejecting certificates that lack a matching SAN. Connecting with an IP address when the certificate lists only DNS:ldap1.example.com commonly fails verification even when port 636 is open.

Always pass -servername with the DNS name the client will use. If no certificate is returned, investigate the listener and server NSS database before you change application LDAP settings.


Fix client CA trust and hostname matching

On the directory server, list the NSS database and identify the issuing CA nickname:

bash
sudo certutil -d /etc/dirsrv/slapd-ldap1/ -L

Sample output:

output
Certificate Nickname                                         Trust Attributes
Self-Signed-CA                                               CT,,
Server-Cert                                                  u,u,u

Export the issuing CA certificate, not the leaf server certificate. Clients trust the CA and then validate the server certificate issued by it.

bash
CA_NICKNAME="Self-Signed-CA"  # Replace with the listed CA nickname
bash
sudo certutil -d /etc/dirsrv/slapd-ldap1/ -L -n "$CA_NICKNAME" -a > /tmp/ds-ca.crt

Copy /tmp/ds-ca.crt from the server to the failing client with scp, configuration management, or your standard file-transfer process.

On a RHEL-family client, install it into the system trust store:

bash
sudo cp /tmp/ds-ca.crt /etc/pki/ca-trust/source/anchors/ds-ca.crt
bash
sudo update-ca-trust

For OpenLDAP utilities, point the client at the same CA explicitly:

bash
LDAPTLS_CACERT=/etc/pki/ca-trust/source/anchors/ds-ca.crt ldapsearch -LLL -x -H ldaps://ldap1.example.com:636 -b "" -s base "(objectClass=*)" namingContexts

Sample output after trust is configured:

output
dn:
namingContexts: dc=example,dc=com

You can also set the default in /etc/openldap/ldap.conf:

text
TLS_CACERT /etc/pki/ca-trust/source/anchors/ds-ca.crt

Do not use TLS_REQCERT never as the permanent fix because it bypasses certificate verification.

Retest from the same host that failed in production, not only from the directory server itself. A connection to ldaps://127.0.0.1:636 can fail when the certificate covers ldap1.example.com only. On a remote client, resolving ldap1.example.com to 127.0.0.1 sends the connection back to that client rather than to the directory server.


Check the server certificate database

List certificates in the instance NSS database:

bash
sudo certutil -d /etc/dirsrv/slapd-ldap1/ -L

Sample output:

output
Certificate Nickname                                         Trust Attributes
Self-Signed-CA                                               CT,,
Server-Cert                                                  u,u,u

Display the active server certificate details. Use the nickname from dsconf ldap1 security rsa get, not an assumed default:

bash
sudo certutil -d /etc/dirsrv/slapd-ldap1/ -L -n "Server-Cert"

Confirm that the active server certificate exists, is not expired, and has an associated private key. In NSS trust flags, u indicates private-key material. Separately confirm that the issuing CA has suitable CA trust flags, commonly C,, or CT,, depending on whether client-certificate authentication is also required.

Also inspect the running configuration:

bash
dsconf ldap1 security certificate list
bash
dsconf ldap1 security ca-certificate list

Sample output (trimmed):

output
Certificate Name: Server-Cert
Subject DN: CN=ldap1.example.com,...
Expires: 2028-07-22 01:18:03
Trust Flags: u,u,u

Finding a certificate in the NSS database does not prove it is the one selected by the active RSA configuration. Compare dsconf ldap1 security rsa get with the certificate list before you renew or replace files.

Certificate import, renewal, replacement, and NSS database recovery belong in certificate management and NSS database troubleshooting, not in this connection guide.


Check network access and TLS compatibility

Test remote reachability of port 636 from the failing client:

bash
nc -vz ldap1.example.com 636

Confirm DNS resolves to the server you intend to reach:

bash
getent hosts ldap1.example.com

Sample output:

output
192.0.2.10      ldap1.example.com

The result must be the intended directory-server or load-balancer address. 127.0.0.1 is valid only when the LDAP client and Directory Server run on the same host; on a remote client it indicates a DNS or /etc/hosts error.

On the directory server, confirm the firewall allows LDAPS when firewalld is in use. A host may allow LDAPS through a named service rule rather than a raw port rule:

bash
sudo firewall-cmd --query-service=ldaps
bash
sudo firewall-cmd --query-port=636/tcp

When both queries return no, open the port or service persistently. Use either the documented port rule or the ldaps service, but avoid adding duplicate rules:

bash
sudo firewall-cmd --permanent --add-port=636/tcp
bash
sudo firewall-cmd --reload

Review the server TLS bounds:

bash
dsconf ldap1 security get | grep -Ei 'sslVersion|cipher'

Test a specific protocol when an old client is suspected:

bash
openssl s_client -connect ldap1.example.com:636 -servername ldap1.example.com -tls1_2 </dev/null

Do not lower sslversionmin until you confirm the client cannot negotiate a supported protocol. Cipher policy details are in TLS cipher configuration. Minimum SSF and secure-bind enforcement are in enforce TLS and secure binds.

When StartTLS works against the same server and certificate but LDAPS fails, prioritize the dedicated port, secure listener address, firewall, and load-balancer configuration. Still confirm that both tests reached the same host rather than different load-balancer backends. When LDAPS works on the directory server host but fails from remote clients, compare firewall rules, network ACLs, load balancer backend ports, and whether the balancer forwards port 389 but not 636.


Inspect logs and verify the fix

Reproduce the client connection while you follow the errors log:

bash
sudo tail -f /var/log/dirsrv/slapd-ldap1/errors

Certificate loading failures, missing private keys, expired certificates, and NSS database problems appear here. A failed TLS handshake may produce no bind line in /var/log/dirsrv/slapd-ldap1/access because the LDAP operation never starts. Successful secure sessions can also appear in /var/log/dirsrv/slapd-ldap1/security.

Repeat the production LDAPS transport test after you apply the fix:

bash
LDAPTLS_CACERT=/etc/pki/ca-trust/source/anchors/ds-ca.crt ldapsearch -LLL -x -H ldaps://ldap1.example.com:636 -b "" -s base "(objectClass=*)" namingContexts

Confirm certificate verification independently with OpenSSL. LDAPTLS_CACERT is an OpenLDAP client variable and does not configure the standalone openssl command:

bash
openssl s_client -connect ldap1.example.com:636 -servername ldap1.example.com -CAfile /etc/pki/ca-trust/source/anchors/ds-ca.crt -verify_hostname ldap1.example.com -verify_return_error </dev/null

Sample output (trimmed):

output
Verify return code: 0 (ok)

Then confirm authentication on the same client:

bash
LDAPTLS_CACERT=/etc/pki/ca-trust/source/anchors/ds-ca.crt ldapwhoami -x -H ldaps://ldap1.example.com:636 -D "cn=Directory Manager" -y /root/dm.pw

Retest the original client: ldapsearch, SSSD, Apache, replication, monitoring, or backup tools against the same hostname and port you repaired. Test every replica directly when a load balancer fronts the topology.


Troubleshooting

Symptom Likely cause Check
Port 389 works but 636 is refused LDAPS listener disabled or blocked ss, firewall, and nsslapd-secureport
LDAPS works locally only Network or firewall restriction Remote nc and firewall rules
LDAPS works only through localhost Secure listener bound to loopback ss and nsslapd-securelistenhost
Can't contact LDAP server (-1) Often certificate verification or handshake failure ldapsearch -d 1 and openssl s_client
Self-signed certificate in chain Client does not trust the issuing CA Client trust store or LDAPTLS_CACERT
Hostname mismatch URI hostname missing from certificate SAN Certificate SAN and client URI
Certificate expired Server presents an expired certificate openssl x509 -dates and certutil -L
StartTLS works but LDAPS fails Dedicated port 636, listener address, or firewall ss, nsslapd-securelistenhost, and secure-port settings
openssl works but ldapsearch fails LDAP client CA configuration ldap.conf and LDAPTLS_CACERT
No peer certificate returned Server did not complete TLS negotiation Listener and errors log
Works with hostname but not IP Certificate covers DNS name only Use the certificate hostname in the URI
Old client cannot connect TLS protocol or cipher incompatibility Protocol negotiation and sslversionmin
Works on one replica only Certificate or TLS configuration differs Test each server directly
TLS succeeds but bind returns error 49 Credentials are incorrect Error 49 troubleshooting guide
TLS succeeds but operation returns error 50 ACI denies the operation Error 50 troubleshooting guide

References


Summary

When LDAP works but LDAPS fails in 389 Directory Server, classify the failure with side-by-side anonymous LDAP, LDAPS, and StartTLS transport tests, then work through the listener on port 636, the TLS handshake, client CA trust, hostname matching, the server NSS certificate database, network access, and TLS compatibility. Treat Can't contact LDAP server (-1) on LDAPS as a transport or verification problem until openssl s_client with -CAfile and -verify_hostname and ldapsearch -d 1 show a completed handshake. After TLS succeeds, test authentication separately and distinguish bind and authorization errors from connection problems.


Frequently Asked Questions

1. Why does LDAP work on port 389 but LDAPS fails on port 636?

Plain LDAP on 389 can succeed while LDAPS still fails on a separate listener, certificate, or network problem. Port 636 may not be listening, a firewall may block it, the client may not trust the issuing CA, or the URI hostname may not match the certificate Subject Alternative Name. StartTLS on 389 isolates whether the dedicated LDAPS port or the shared TLS configuration is at fault.

2. What does ldap_sasl_bind Cant contact LDAP server (-1) mean for LDAPS?

Error -1 often appears when the LDAP client never completes a usable TLS session. Certificate verification failure, connection refusal, and DNS or routing problems can all surface as -1 before any LDAP bind result is returned. Run ldapsearch with -d 1 or test with openssl s_client to see whether the failure is network, handshake, or trust related.

3. Can I fix LDAPS by setting TLS_REQCERT never?

That bypasses certificate verification and should not be the permanent fix. Import the issuing CA into the client trust store, align the client URI hostname with the certificate SAN, and renew expired certificates on the server. Use TLS_REQCERT never only as a short controlled diagnostic, not as production policy.

4. StartTLS works but LDAPS fails — what should I check first?

StartTLS negotiates TLS on the existing LDAP port 389. LDAPS uses a dedicated listener, usually port 636. When StartTLS works but ldaps:// fails, inspect ss for :636, nsslapd-secureport, nsslapd-securelistenhost, and remote firewall rules. Confirm both tests reached the same host rather than different load-balancer backends before you change certificate files.

5. TLS succeeds but ldapwhoami returns error 49 — is that an LDAPS problem?

No. When openssl s_client or ldapsearch -d 1 shows a completed TLS handshake, LDAPS transport is working. Error 49 is an authentication failure. Use the invalid-credentials troubleshooting guide for bind DN and password problems instead of repeating certificate work.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …