Active Directory · Troubleshooting

LDAP Bind Failures After LDAP Signing and Channel Binding Enforcement

When a domain controller starts rejecting unsigned or clear-text LDAP binds, legacy applications break with “strong authentication required” — the fix is to find every offending client from Event 2889 first, remediate them, and only then enforce.

Quick idea: LDAP signing and channel binding force applications to prove their LDAP traffic has not been tampered with. Older apps that send credentials unsigned, or in clear text over port 389, stop working the moment a DC requires it. The safe path is never to flip enforcement blind — it is to log who is still binding insecurely, fix those clients, and enforce once the log goes quiet.
LDAP signing

Requires SASL binds to be integrity-signed, so traffic cannot be silently altered in transit.

Channel binding

Ties an LDAPS session to its TLS channel, defeating relay attacks that reuse credentials elsewhere.

Event 2889

Names each client still binding insecurely — its IP and the account it used. Your remediation list.

Introduction

A monitoring appliance, a printer’s address-book sync, an HR system, or a home-grown script stops authenticating against Active Directory. The application reports that the LDAP bind failed, sometimes with the words “strong authentication required”. Nothing changed in the application. What changed is the domain controller — either an administrator enabled signing enforcement, or a Windows update or a newer Server build turned it on by default.

This is a security-hardening collision, not a bug. Microsoft has spent several release cycles pushing LDAP signing and channel binding from optional to default, and Windows Server 2025 domain controllers enforce LDAP signing out of the box. Anything still doing unsigned SASL binds, or simple binds over unencrypted port 389, is exactly what the hardening is designed to reject. The work is finding those clients before enforcement finds them for you.

What You’re Seeing

On the client side, the bind fails; on the domain controller, the Directory Service log tells the real story. Three events matter, and knowing which you are seeing tells you where you stand:

# Client-side symptom (e.g. from ldp.exe or an app log)
Ldap_simple_bind_s() failed: Strong Authentication Required

# DC Directory Service log - a client bound INSECURELY (detailed log)
Event ID 2889  Source: Microsoft-Windows-ActiveDirectory_DomainService
The following client performed a SASL LDAP bind without requesting
signing, or a simple bind over a clear text connection.
  Client IP address: 10.20.3.44:51022
  Identity the client attempted to authenticate as: CORP\svc-scan

# DC log - 24-hour SUMMARY of insecure binds still being permitted
Event ID 2887  Number of ... binds performed without signing: 128
Key difference: Event 2887 is a 24-hour count of insecure binds the DC still allows — you are not enforcing yet, and you have clients to fix. Event 2888 is the count the DC has begun rejecting — enforcement is on and something is now broken. Event 2889 is the per-client detail that names exactly who to fix.

What It Actually Means

Unsigned LDAP traffic can be altered in transit, and clear-text simple binds send credentials in the open — both are replay and man-in-the-middle risks. LDAP signing requires SASL binds (Negotiate, Kerberos, NTLM, Digest) to be integrity-signed so tampering is detectable. Channel binding goes further for LDAPS: it cryptographically ties the authentication to the specific TLS channel, so a captured bind cannot be relayed onto a different connection.

A domain controller can be in one of three states for signing: it advertises the requirement but still accepts insecure binds (audit), or it rejects them (enforce). The failure you are troubleshooting means a DC moved to reject while a client was still binding the old way. That client is doing something the security basics post would flag — sending authentication that a passive attacker on the wire could reuse.

Step 1: Turn On Detailed Logging

Before changing any enforcement setting, make the domain controllers name their insecure clients. Raise the LDAP Interface Events diagnostic to level 2 so each insecure bind logs an Event 2889 with the client IP and account.

# On each DC: enable per-client insecure-bind logging (Event 2889)
reg add "HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics" /v "16 LDAP Interface Events" /t REG_DWORD /d 2 /f

# Collect the 2889 events - each names an offending client
Get-WinEvent -LogName 'Directory Service' |
    Where-Object { $_.Id -eq 2889 } |
    Select-Object TimeCreated, Message

# Also watch the daily summary counts (2887 permitted / 2888 rejected)
Get-WinEvent -LogName 'Directory Service' |
    Where-Object { $_.Id -in 2886,2887,2888 } |
    Select-Object TimeCreated, Id
Important: Do this on every domain controller, not just one. Clients bind against whichever DC answers, so an appliance that looks clean against DC01 may be binding insecurely against DC03. You need the union of 2889 events from all DCs before you can trust the list is complete.

Step 2: Build the Offender List

Turn the 2889 stream into a deduplicated inventory of client IPs and accounts. This list is the project — every entry must be remediated before enforcement is safe.

# Extract distinct client IPs from the 2889 events on a DC
Get-WinEvent -LogName 'Directory Service' |
    Where-Object { $_.Id -eq 2889 } |
    ForEach-Object { ($_.Properties[0].Value) } |
    Sort-Object -Unique

# Cross-check the daily volume trend - it should fall toward zero
Get-WinEvent -LogName 'Directory Service' |
    Where-Object { $_.Id -eq 2887 } |
    Select-Object TimeCreated, Message -First 5
Troubleshooting note: Map each IP to a real system before touching it. Common offenders are network appliances and printers doing LDAP address lookups, monitoring and backup tools, Linux/Unix hosts using ldapsearch or SSSD without TLS, and in-house scripts using simple binds on port 389. The account in the event tells you which integration it is.

Step 3: Remediate the Clients

Fix the clients, not the domain controllers. The goal is that every application either signs its SASL binds or uses LDAPS (port 636) instead of clear-text 389.

# For Windows clients, require the LDAP client to sign:
# GPO: Computer Configuration > Policies > Windows Settings >
#   Security Settings > Local Policies > Security Options >
#   "Network security: LDAP client signing requirements" = Require signing

# For appliances/scripts: switch the connection from 389 to LDAPS 636,
# or enable signing/TLS in the application's LDAP configuration.

# Verify a client can bind securely with ldp.exe:
#   Connection > Connect > port 636 (SSL ticked) > Bind
# A successful secure bind is the proof a client is remediated.
Production note: Do not enable enforcement to “flush out” the last few clients. That trades a controlled audit for an uncontrolled outage — the remaining insecure integrations will simply stop, often ones you did not know existed. Drive the 2887 count to zero first, then enforce.

Common Causes

The clients that break are predictable. These are the usual sources of insecure binds, with how to confirm and fix each.

Cause How to Confirm Fix
App uses simple bind on port 389 Event 2889 shows “simple bind”; app config points at 389. Switch the app to LDAPS (636), or enable TLS on the connection.
SASL bind without signing Event 2889 shows a Negotiate/NTLM bind without integrity. Enable signing in the client/library, or require client signing by GPO.
Appliance / printer LDAP lookup 2889 client IP maps to a device doing address-book or auth lookups. Reconfigure the device to use LDAPS; update firmware if it lacks TLS.
Linux/Unix host (SSSD, ldapsearch) Non-Windows IP binding on 389 without TLS. Configure ldaps:// or StartTLS and trust the DC’s CA.
In-house script or service account 2889 account is a known service account; code uses a plain bind. Update the code to sign or use LDAPS before enforcing.
DC hardened by update / Server 2025 default Failures began after patching or a DC rebuild; 2888 appears. Confirm the enforcement state; audit-first if clients are not ready.
Channel binding on LDAPS App uses LDAPS but an old TLS stack fails CBT. Update the client TLS library so it supports channel binding tokens.

Enforcing Safely

Once the 2889 stream is empty and the 2887 daily count has held at zero for a sensible window, you can require signing on the domain controllers. The setting lives in the Default Domain Controllers Policy: Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options > “Domain controller: LDAP server signing requirements”, set to Require signing. Channel binding has its own companion setting for LDAPS.

After enabling it, verify from a client with ldp.exe: a simple bind on port 389 should now be refused with “strong authentication required”, while a signed or LDAPS bind succeeds. Watch for Event 2888 — the rejection summary — and treat any appearance of it as a client you missed, not as expected noise. Roll the change out DC by DC if the environment is large, so any surprise is contained.

Better approach: Keep the detailed logging on through the first days of enforcement. If something you missed breaks, the same 2889 events that built your audit list will name it immediately, and you can remediate that one client instead of rolling the whole change back.

How to Prevent It

The recurring version of this problem is new insecure clients creeping in after you enforced. Make LDAPS the default for every new integration — when a vendor asks for LDAP details, give them 636 and a signing requirement, never 389 with a simple bind. Keep the LDAP Interface Events logging available so a periodic check for Event 2889 catches a newly added appliance before it becomes an incident.

Treat this as part of routine security posture rather than a one-off migration. New Windows Server builds ship progressively stricter defaults, so an environment that standardised on signed binds and LDAPS years ago simply inherits each tightening for free, while one that relies on clear-text binds re-lives this outage with every upgrade. Pair it with the wider hardening covered in the security basics post.

Quick Reference

Item Meaning / Use
Event 2886Reminder that the DC is not yet requiring signing.
Event 288724-hour count of insecure binds still permitted — clients left to fix.
Event 288824-hour count of insecure binds now rejected — enforcement is on.
Event 2889Per-client detail — the IP and account of an insecure bind.
16 LDAP Interface Events = 2Diagnostic registry value that turns on 2889 logging.
“Domain controller: LDAP server signing requirements”The server-side GPO — set to Require signing to enforce.
“Network security: LDAP client signing requirements”The client-side GPO — makes Windows clients sign.
Port 636 (LDAPS)The encrypted alternative to clear-text 389.

Final Thoughts

LDAP signing and channel binding failures feel sudden, but they are the predictable result of a security floor rising to meet clients that never moved off the floor. The domain controller is doing its job; the broken application is doing something it should have stopped doing years ago. The mistake is treating enforcement as the first step instead of the last.

Log first, remediate the named clients, then enforce with the logging still running. Done in that order, a change that can cause a domain-wide authentication outage becomes a quiet, controlled tightening that no user ever notices.

Key takeaway: Never enforce blind. Set 16 LDAP Interface Events to 2 on every DC, collect Event 2889 to build a list of every insecure client by IP and account, remediate each to sign or use LDAPS (636), and only enable “Require signing” once the Event 2887 daily count has held at zero. Keep logging on through enforcement so a missed client names itself.
More troubleshooting

Next in the troubleshooting series: diagnosing slow domain logons and long Group Policy processing — separating the network, the DC, and the client-side extensions that quietly add minutes to every sign-in.