Helpdesk: "Since we added DC3 on Windows Server 2025 last week, the door-badge server's directory sync fails with 'Strong Authentication Required' whenever it lands on DC3. The firewall's LDAPS test against DC2 says 'Cannot open connection' since DC2's certificate renewed, and every DC logs Event 2887 once a day. A forum post says to turn LDAP signing off in the Default Domain Controllers Policy, delete the old certificates on DC2, and set channel binding to Never. Can we start with that?"

Not yet. "LDAPS not working" and "LDAP signing required" are two different breaks that show up in the same week. LDAPS on port 636 fails when the domain controller has no certificate it can use, serves a different certificate than you think, or serves one the client doesn't trust or can't match to the name it used. Signing and channel binding failures are binds the DC now rejects on purpose. Microsoft: "There's no user interface for configuring LDAPS. Installing a valid certificate on a domain controller permits the LDAP service to listen for, and automatically accept, SSL connections for both LDAP and global catalog traffic." On signing, Microsoft's own warning: "After you make this configuration change, clients that rely on unsigned SASL (Negotiate, Kerberos, NTLM, or Digest) LDAP binds or on LDAP simple binds over a non-SSL/TLS connection stop working." Turning signing off domain-wide, deleting certificates, or setting channel binding to Never each removes evidence you need, and the first and last reopen the attacks those settings exist to stop. Work through it as a chain: which client, which DC, which port, which bind → does the DC listen on 636 and does the client reach it? → does the DC have a certificate it can use (Event 1220)? → which certificate does it actually serve? → does the client trust that certificate? → does the name the client used match it? → who is binding unsigned (Events 2887 and 2889)? → which signing policy is actually in effect on each DC? → is channel binding rejecting a TLS bind? Test-NetConnection, Get-ChildItem Cert:\LocalMachine\My, certutil, Get-WinEvent, reg query, gpresult, and ldp.exe are the sources for that chain. Turn signing off everywhere and you'll find out later which client was sending passwords in clear text.

If the DC never got a certificate because enrollment fails, Certificate Autoenrollment Not Working covers the GPO, template, and CA side. If certutil on the client fails the revocation check, Revocation Server Was Offline 0x80092013 covers CRLs and CDPs. This post covers "LDAPS on port 636 (or 3269) to a domain controller fails, an application or appliance gets 'Strong Authentication Required' after LDAP signing changes or a new Windows Server 2025 DC, or Directory Service Events 1220, 2886, 2887, 2889, 3039, or 3075 appear, and you need a read-first path before you replace certificates, restart DCs, change signing or channel binding policy, or edit NTDS registry values."

TL;DR

  • LDAPS is a certificate problem first. Microsoft's requirements include: "The Enhanced Key Usage extension includes the Server Authentication (1.3.6.1.5.5.7.3.1) object identifier (also known as OID)." and the DC's FQDN in the subject CN or a SAN DNS entry (Step 3).
  • The DC may not serve the certificate you're looking at. Microsoft: "If there is a certificate in the NT Directory Services (NTDS) store, DC use the certificate in the NTDS store instead." (Step 4).
  • The client has to trust it. Microsoft: "The certificate was issued by a CA that the domain controller and the LDAPS clients trust." (Step 5).
  • Event 2889 names the unsigned clients. Microsoft: "The log entry displays the IP address of the client and the identity that the client tried to use to authenticate." It's off until you raise a diagnostic level (Step 7).
  • Windows Server 2025 changes the default. Microsoft: "Windows Server 2025 or later requires LDAP signing by default for new Active Directory deployments." (Step 8).
  • Channel binding only covers TLS plus SASL. Microsoft: "LDAP channel binding applies through the Domain controller: LDAP server channel binding token requirements policy only to TLS-secured sessions that use Simple Authentication and Security Layer (SASL) authentication." (Step 9).

Where in the chain did it break?

Step What should be true Typical symptom when it breaks
1. Symptom captured Which client, which DC, which port, which bind type, since when "LDAP is broken" with no DC or port named
2. Port and listener The DC listens on 636 (and 3269 on a global catalog) and the client reaches it TCP test fails; nothing listening
3. A usable certificate The DC holds a Server Authentication certificate with its FQDN and a private key Event 1220 on the DC, Schannel 36886
4. The served certificate You know which certificate the DC presents on 636 Renewed certificate in the store, old one still served
5. Client trust The client builds a valid chain and can check revocation Untrusted root, expired, revocation offline
6. Name match The name the client uses is in the certificate Works by FQDN, fails by domain name, alias, or IP
7. Unsigned binds You know who binds unsigned or in clear text on 389 Event 2887 every day, no client named
8. Policy in effect You know each DC's signing setting, including the 2025 enforcement policy One DC rejects, the others allow
9. Channel binding You know whether TLS + SASL binds would fail CBT Events 3039, 3074, or 3075
10. Change Only after Steps 1-9 agree: one link, one change Signing off everywhere, same failure

Step 1: Capture the symptom (read-only)

Write these on the ticket first:

Fact Why it matters
Which client or application A Windows computer, an appliance, a Java or Linux app, a SaaS connector. Microsoft splits devices into appliances, non-Windows devices, and Windows devices when it plans signing and channel binding
Which DC, and how the client finds it A single DC FQDN, the domain name (which resolves to any DC), a load-balanced or alias name, or an IP address. The certificate has to carry the name used (Step 6)
Which port 389 (LDAP), 636 (LDAPS), 3268 (global catalog), 3269 (global catalog over SSL). Microsoft: "LDAPS communication occurs over port TCP 636. LDAPS communication to a global catalog server occurs over TCP 3269."
Which bind type Simple bind (a DN or user name and password) or SASL (Negotiate, Kerberos, NTLM). Signing and channel binding treat them differently (Steps 7 and 9)
Exact error text "Cannot open connection" in ldp, "Strong Authentication Required", a TLS or certificate error in the app's log, or a timeout
Since when, and what changed A certificate renewal, a new CA, a new DC (especially Windows Server 2025), a GPO change, a TLS hardening change, a firewall change

Then branch on what you see:

What you see What it usually means (our reading unless noted) Start at
Timeout on 636, or the TCP test fails Firewall, routing, or nothing listening Step 2
Event 1220 on the DC, or "Cannot open connection" in ldp on 636 No usable certificate. Microsoft's Event 1220 text: "LDAP over Secure Sockets Layer (SSL) will be unavailable at this time because the server was unable to obtain a certificate." Step 3
LDAPS broke right after a renewal The DC still serves the old certificate, or picked a different one Step 4
Windows clients work, an appliance or Java app fails on 636 The app doesn't trust your CA, or uses a name not in the certificate Steps 5 and 6
Works by DC FQDN, fails by domain name or alias Name not in the certificate Step 6
"Strong Authentication Required" on 389 The DC requires signing; the client sends a simple bind in clear text or an unsigned SASL bind Steps 7 and 8
Only one DC rejects binds That DC's signing policy differs, often a new Windows Server 2025 DC Step 8
Events 3039, 3074, or 3075 TLS + SASL binds without a valid channel binding token Step 9

Step 2: Does the DC listen on 636, and does the client reach it? (read-only)

Start at the network, because nothing else matters if the handshake never starts. From the failing client, or a Windows box on the same network segment:

# Read-only. From the client side: can it open TCP 636 (and 3269 for the global catalog) on the DC it uses? Test-NetConnection -ComputerName DC2.contoso.com -Port 636 Test-NetConnection -ComputerName DC2.contoso.com -Port 3269 

On the DC itself:

# Read-only. On the DC: is anything listening on 636 and 3269? Get-NetTCPConnection -LocalPort 636, 3269 -State Listen -ErrorAction SilentlyContinue | Select-Object LocalAddress, LocalPort, State, OwningProcess | Format-Table -AutoSize 
Finding What it means (our reading unless noted) Next
TcpTestSucceeded : False from the client, listener present on the DC A firewall or route between them Fix the path; Microsoft's port reference lists LDAP SSL on TCP 636 and Global Catalog on TCP 3268 and 3269
Listener present, TCP test succeeds The port is fine; the problem is in the TLS handshake or the bind Step 3
No listener on 636 Unusual for a DC; the LDAP service may not be running Check the AD DS service and the Directory Service log before going further
3269 fails but 636 works The DC isn't a global catalog, or the app should use 636 Point the app at a GC or at 636

A port that answers isn't the same as LDAPS working. The TCP test only proves the socket opens; a DC with no certificate still accepts the connection and then fails the TLS handshake (our reading of Microsoft's Event 1220 text and the Schannel 36886 description).

Step 3: Does the DC have a certificate it can use? (read-only)

Microsoft's requirements for an LDAPS certificate, in short: it sits in the Local Computer's Personal store, "A private key that matches the certificate is present in the Local Computer's store and is correctly associated with the certificate," the private key doesn't have strong protection, the EKU includes Server Authentication, the DC's Active Directory FQDN is the subject CN or a SAN DNS entry, and it chains to a CA both the DC and the clients trust.

First, the DC's own log. Microsoft: "Event ID 1220 is logged on a domain controller when client computers attempt to make an LDAP-over-SSL connection to the directory when SSL connections are not enabled on the directory." Schannel logs its side in the System log; Microsoft's Schannel reference describes Event 36886 as occurring "when a server attempt to make an SSL connection but no server certificate is found."

# Read-only. On the DC: Event 1220 (Directory Service) and Schannel 36886 (System), last 7 days $since = (Get-Date).AddDays(-7) Get-WinEvent -FilterHashtable @{ LogName = 'Directory Service'; Id = 1220; StartTime = $since } -ErrorAction SilentlyContinue | Select-Object TimeCreated, Id, Message | Format-List Get-WinEvent -FilterHashtable @{ LogName = 'System'; ProviderName = 'Schannel'; Id = 36886; StartTime = $since } -ErrorAction SilentlyContinue | Select-Object TimeCreated, Id, Message | Format-List 

Then the certificates in the computer's Personal store that could serve LDAPS:

# Read-only. On the DC: Server Authentication certificates in the computer's Personal (MY) store Get-ChildItem -Path Cert:\LocalMachine\My -SSLServerAuthentication | Select-Object Subject, Issuer, NotBefore, NotAfter, HasPrivateKey, Thumbprint, DnsNameList, EnhancedKeyUsageList | Format-List 

And Microsoft's validity check from the Directory Services team, which also reports the private key:

:: Read-only. On the DC: verify each certificate in the computer's Personal store (Microsoft's AskDS form) certutil -verifystore MY 

Per that post, a good certificate shows "Encryption test passed", the Server Authentication policy under "Verified Application Policies", and "Certificate is valid" at the end. The missing-key case reads "No key provider information" and "Missing stored keyset".

Finding What it means (Microsoft unless noted) Next
No Server Authentication certificate at all Microsoft: "If you want to configure a domain controller or an AD LDS server to support SSL connections, you must provide a certificate for the AD DS or AD LDS directory to use." Step 10, and the autoenrollment post if enrollment fails
HasPrivateKey is False, or "Missing stored keyset" AskDS: "The normal cause of this problem is that the certificate request was generated on one machine and we have installed the certificate on a different machine." Step 10
NotAfter is in the past Expired. AskDS: "You cannot renew a certificate once it has expired." Step 10 (new certificate)
The FQDN isn't in Subject or DnsNameList Fails the name requirement Step 6
Several valid certificates Microsoft: "If there are multiple valid certificates available in the local computer store, Schannel may not select the correct certificate." Step 4
One good certificate, Event 1220 still logged after it was added The DC may not have reloaded it yet (our reading) Step 4

If you see no 1220 and no 36886 but LDAPS still fails, the DC probably has a certificate; the question moves to which one it serves and whether the client accepts it (our reading).

Step 4: Which certificate does the DC actually serve? (read-only)

This is where renewals go wrong. Three Microsoft statements together explain it. The NTDS store wins: "AD DS preferentially looks for certificates in this store over the Local Machine's store." In the computer store, the pick isn't predictable: "Schannel, the Microsoft SSL provider, selects the first valid certificate that it finds in the local computer store." And on newer versions: "Finally, if a Windows Server 2008 or a later version domain controller finds multiple certificates in its store, it will random chose one of these certificates." Microsoft's LDAPS troubleshooting article adds: "A conflict with a certification authority (CA) certificate may occur if the CA is installed on a domain controller that you are trying to access through LDAPS."

So read what the DC presents on the wire, not what's in the store. This asks the DC for its certificate the same way an LDAPS client would and prints it, without trusting it:

# Read-only. From the client side: which certificate does DC2 present on 636? (our form, using .NET SslStream) # The validation callback returns $true so you can see an untrusted or wrong certificate instead of an exception $dc = 'DC2.contoso.com' $tcp = New-Object System.Net.Sockets.TcpClient($dc, 636) $ssl = New-Object System.Net.Security.SslStream($tcp.GetStream(), $false, { $true }) try { $ssl.AuthenticateAsClient($dc) $served = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($ssl.RemoteCertificate) $served | Select-Object Subject, Issuer, NotBefore, NotAfter, Thumbprint, DnsNameList | Format-List # Save it for Step 5 (public certificate only) [System.IO.File]::WriteAllBytes("$env:TEMP\dc2-ldaps.cer", $served.Export('Cert')) } finally { $ssl.Dispose(); $tcp.Dispose() } 

Change the port to 3269 to read the global catalog side. If AuthenticateAsClient throws before any certificate comes back, the DC had nothing to offer, which matches Event 1220 (our reading).

Compare the served Thumbprint with Step 3's list. Then look in the NTDS store, which the computer-store listing doesn't show. Microsoft's route is the Certificates snap-in: Service account → Local computer → Active Directory Domain Services, then NTDS\Personal. A command-line read (our form; the -service option is documented as accessing "a machine service store"):

:: Read-only. On the DC: certificates in the AD DS service's own Personal store (our form; use the MMC route if it errors) certutil -service -store NTDS\My 
Finding What it means (Microsoft unless noted) Next
Served thumbprint = an old or expired certificate, new one in the computer store The DC hasn't reloaded. Microsoft's older guidance: "the server must be restarted for Schannel to use the new certificate." Newer DCs can reload without a restart Step 10 (renewServerCertificate)
Served certificate is in the NTDS store, not the one you renewed The NTDS store wins Replace it there (Step 10)
Served certificate is the CA's own certificate, or another Server Authentication certificate Several candidates; the DC chose one you didn't intend Put the intended certificate in the NTDS store (Step 10)
Served certificate is the one you expected The DC side is right Step 5

Step 5: Does the client trust that certificate? (read-only)

Microsoft's LDAPS troubleshooting article checks the chain from the client, with the certificate exported from the server: certutil -v -urlfetch -verify serverssl.cer > output.txt, then "Open the Output.txt file, and then search for errors." The file saved in Step 4 is the certificate the DC actually served, so use that one:

:: Read-only. On the CLIENT (or a Windows box with the same trust store): build the chain and fetch AIA and CDP URLs certutil -v -urlfetch -verify %TEMP%\dc2-ldaps.cer > %TEMP%\dc2-ldaps-verify.txt findstr /i "error expired revoked untrusted incomplete offline" %TEMP%\dc2-ldaps-verify.txt 

-urlfetch is documented as "Retrieve and verify AIA Certs and CDP CRLs." Microsoft's AskDS post lists what the bottom of the output usually says when it fails:

certutil says What it means (Microsoft unless noted) Next
"Expired certificate" Past its validity period. AskDS: "Now it's possible that the system clock has been changed to an invalid date." Check the clock first (Windows Time Not Syncing With Domain Controller), then Step 10
"Verifies against UNTRUSTED root" Per AskDS, a certificate in the chain is missing from the client's Intermediate Certification Authorities store (for an intermediate) or Trusted Root Certification Authorities store (for a root) Step 10 (trust on the client)
"Incomplete certificate chain" An intermediate certificate can't be found or fetched Step 10
"Certificate is REVOKED" AskDS: "the certificate has been revoked and therefore a new certificate needs to be issued." Step 10 (new certificate)
"Revocation check skipped" or the revocation server is offline The client can't reach a CDP Revocation Server Was Offline
Verifies clean The chain is fine on this client Step 6

Non-Windows clients (appliances, Java, Linux) don't use the Windows trust store. A clean certutil run on a Windows box proves the chain is buildable; the appliance still needs your root and intermediate imported into its own store (our reading). Microsoft's own requirement covers both sides: "Trust is established by configuring the clients and the server to trust the root CA to which the issuing CA chains."

The same server-certificate pattern (right EKU, private key present, chain the client trusts) is what breaks PEAP on NPS; NPS Event 6273 Reason Code 16 or 22 walks that version.

Step 6: Does the name the client used match the certificate? (read-only)

Microsoft's name rule: "The Active Directory fully qualified domain name of the domain controller (for example, dc01.contoso.com) must appear in one of the following places:" the subject CN or a DNS entry in the SAN. A client that connects by the domain name (contoso.com), a load-balancer or alias name (ldap.contoso.com), or an IP address checks that name instead, and a certificate issued only to DC2.contoso.com fails that check (our reading).

# Read-only. On a Windows client: does the served certificate pass SSL policy for the name the app uses? # (Microsoft's Test-Certificate example uses -Policy SSL -DNSName 'dns=contoso.com'; the file is the one saved in Step 4) $served = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("$env:TEMP\dc2-ldaps.cer") $served.DnsNameList Test-Certificate -Cert $served -Policy SSL -DNSName 'dns=DC2.contoso.com' Test-Certificate -Cert $served -Policy SSL -DNSName 'dns=ldap.contoso.com' 

Microsoft's Test-Certificate reference: "If the DNSName parameter is used, then the DNS subject alternative name is used to verify SSL policy." Then read the application's LDAP server setting and the name it uses, and check that name in DNS:

# Read-only. Where does the name the app uses resolve? (names are examples) Resolve-DnsName -Name ldap.contoso.com -DnsOnly Resolve-DnsName -Name contoso.com -Type A -DnsOnly 
Finding What it means (our reading unless noted) Next
The app uses contoso.com It reaches whichever DC DNS returns, and that DC's certificate needs contoso.com in its SAN Point the app at a DC FQDN, or reissue with the extra SAN (Step 10)
The app uses an alias or load-balancer name That name isn't in any DC's certificate Same choice
The app uses an IP address A certificate issued to DNS names won't match an IP address Use a name
Test-Certificate passes for the name used The name isn't the problem Step 7 if the failure is on 389, or back to Step 5 for the app's own trust store

The Directory Services team's older post adds a caveat for multi-name certificates: "The first name in the SAN has to match the FQDN of the server." Keep the DC's own FQDN first when you reissue (our habit).

Step 7: Who is binding unsigned or in clear text? (read-only, then one low-risk logging change)

This is the 389 side. Microsoft's definition of what the DC counts, from the Event 2889 text: "The following client performed a SASL (Negotiate/Kerberos/NTLM/Digest) LDAP bind without requesting signing (integrity verification), or performed a simple bind over a clear text (non-SSL/TLS-encrypted) LDAP connection."

The DC already logs summaries without any change:

Event When it's logged (Microsoft) What it tells you
2886 At startup, as a reminder when the DC doesn't require signing This DC accepts unsigned binds
2887 "a summary Event ID 2887 one time every 24 hours to indicate how many such binds occurred" How many, not who
2888 "a summary Event ID 2888 one time every 24 hours when such bind attempts occur" on a DC that rejects them How many were rejected
2889 One per bind, only with the diagnostic level raised Client IP, port, identity, and binding type

Read the summaries on every DC first:

# Read-only. Every DC: the latest LDAP signing summaries (2886, 2887, 2888) from the Directory Service log foreach ($dc in (Get-ADDomainController -Filter *).HostName) { Get-WinEvent -ComputerName $dc -FilterHashtable @{ LogName = 'Directory Service'; Id = 2886, 2887, 2888 } -MaxEvents 3 -ErrorAction SilentlyContinue | Select-Object @{ n = 'DC'; e = { $dc } }, TimeCreated, Id, Message | Format-List } 

The 2887 message ends with the two counts that matter: "Number of simple binds performed without SSL/TLS" and "Number of Negotiate/Kerberos/NTLM/Digest binds performed without signing". A DC that logs 2888 instead is already rejecting them, which is the "Strong Authentication Required" side.

To get names, raise the LDAP Interface Events level. Microsoft: "You can enable this additional logging by setting the 16 LDAP Interface Events diagnostic setting to 2 (Basic)." and, for the cost, "it has a negative effect on domain controller performance, and it should be disabled when it is no longer needed." Microsoft's command (a change, but a reversible logging change; do it on one DC at a time, our habit):

:: Low-risk change, on ONE DC. Raise LDAP Interface Events to 2 (Basic) to log Event 2889 per bind (Microsoft's form) reg query HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics /v "16 LDAP Interface Events" Reg Add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics /v "16 LDAP Interface Events" /t REG_DWORD /d 2 

Leave it long enough to cover the clients' schedules (a nightly sync, a weekly report), then group what it logged:

# Read-only. On that DC: unsigned or clear-text binds in the last 24 hours, grouped by client, identity, and binding type # (the property order IP:port, identity, binding type is our reading of the event text; check one event with Format-List first) Get-WinEvent -FilterHashtable @{ LogName = 'Directory Service'; Id = 2889; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue | ForEach-Object { [pscustomobject]@{ Client = $_.Properties[0].Value -replace ':\d+$', '' Identity = $_.Properties[1].Value BindType = $_.Properties[2].Value } } | Group-Object -Property Client, Identity, BindType | Sort-Object -Property Count -Descending | Select-Object Count, Name | Format-Table -AutoSize 

Microsoft's binding types in the 2889 text: "0 - SASL Bind that does not use signing" and "1 - Simple Bind that does not support signing".

Finding What it means (our reading unless noted) Next
Type 1 from an appliance or app with a service account A simple bind with a password on 389, in clear text Move it to LDAPS on 636 (Steps 3-6 for its DC) or to a signed SASL bind (Step 10)
Type 0 from a Windows computer A client or app that asks for SASL without signing; Microsoft says Windows clients request signing by default, so look at the app or a local policy set to None Step 8 (client side)
Type 0 or 1 from an IP you can't place Microsoft: "Identify the make, model, and type of device for each IP address cited by:" Event 2889 Find the owner before anything else
No 2889 after a full cycle, and 2887 counts are zero Nothing on this DC binds unsigned Repeat on the next DC

Then turn it back down. Microsoft's revert: Reg Add HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics /v "16 LDAP Interface Events" /t REG_DWORD /d 0. The diagnostic logging article: "Make sure that you reset the entries to 0 after you finish investigating the problem."

Step 8: Which signing policy is actually in effect on each DC? (read-only)

Microsoft maps the Domain controller: LDAP server signing requirements policy to one registry value, LDAPServerIntegrity under NTDS\Parameters, with None = 1 and Require Signing = 2. Channel binding is LdapEnforceChannelBinding in the same key (Never = 0, When Supported = 1, Always = 2). Read both on every DC, plus the policy result:

:: Read-only. On each DC: the signing and channel binding values it holds (an error means the value isn't set) reg query HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters /v LDAPServerIntegrity reg query HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters /v LdapEnforceChannelBinding :: Which GPO set them (open the report and search Security Options for "LDAP") gpresult /scope computer /h %TEMP%\dc-rsop.html 

Windows Server 2025 adds a second policy. Microsoft: "The Domain controller: LDAP server signing requirements enforcement policy takes precedence over the Domain controller: LDAP server signing requirements policy." Its Not Configured state isn't neutral: "Default: Not Configured, which has the same effect as Enabled (default for new deployments)." And for upgrades and mixed domains: "During an upgrade, Windows Server preserves existing signing policies to prevent disruption; if no LDAP server signing policy exists, Windows Server 2025 requires signing by default."

<...Source:https://dev.to/adminpackstudio/ldaps-not-working-on-a-domain-controller-a-read-first-certificate-ldap-signing-and-event-2889-4777

Related posts

Finding What it means (our reading unless noted) Next
Only the new Windows Server 2025 DC rejects binds No signing policy defined, so that DC requires signing by default; the older DCs still accept unsigned binds