Direct answer: LDAP signing and LDAP channel binding protect different sessions, so audit them separately before enforcing either.
- LDAP signing applies to SASL binds on port 389 without TLS. Enforcing it also rejects simple binds over unencrypted connections.
- Channel binding applies to SASL binds over TLS (LDAPS or STARTTLS), where it closes the NTLM relay gap.
To find who would break, use the Directory Service event log on each domain controller:
- 2887 counts unsigned or clear-text binds the DC allowed in the last 24 hours.
- 2889 names each client's IP address and identity, once the
16 LDAP Interface Eventsdiagnostic level is raised to 2. - 3039, 3074 and 3075 identify clients that would fail channel binding.
Fix or reconfigure each named client, then enforce. Check for a Windows Server 2025 domain controller first: in a new AD deployment on 2025, signing is already required by default and channel binding defaults to "When supported" with auditing on.
Why it matters
Unsigned LDAP and plain simple binds let an attacker on the network path alter directory responses or read credentials. Microsoft has been moving the defaults towards enforcement for several years (security advisory ADV190023, KB4520412, and the Windows Server 2025 defaults). Enforcing without an audit is the usual cause of the morning when the scanners stop sending to email, the firewall's user mapping fails, the HR application can't log anyone in, and the old Linux box can't resolve groups.
Those devices and applications almost always use a simple bind with a service account over port 389, or an older library that does not request signing. They are rarely owned by the AD team. The real work is finding them and their owners before the change, not the change itself.
How it works
What each protection covers
Microsoft's current LDAP signing and channel binding pages separate four layers:
| Protection | What it provides | Applies to |
|---|---|---|
| LDAP signing | Integrity and authenticity, not confidentiality | Non-TLS SASL sessions on port 389 |
| SASL sealing | Confidentiality, integrity and server identity | Non-TLS SASL sessions on port 389 |
| TLS (LDAPS on 636, or STARTTLS on 389) | Confidentiality, integrity and server identity | All session types over TLS |
| Channel binding (CBT) | Ties the SASL authentication to the specific TLS session, preventing relay | TLS + SASL sessions only |
Several consequences follow:
- Signing does not protect simple binds. A simple bind's credentials are protected only by TLS. When a DC requires signing, it rejects simple binds over unencrypted connections. That is the part that breaks most appliances.
- Signing does not apply on TLS sessions, because TLS already provides integrity. A client on LDAPS is not affected by the signing requirement.
- Channel binding does not apply to simple binds over TLS, to certificate binds over TLS, or to non-TLS SASL sessions. An appliance doing a simple bind over LDAPS is not affected by channel binding enforcement, but it is still exposed to whatever its TLS validation allows.
- Microsoft recommends SASL with Kerberos for LDAP authentication. With NTLM, signing detects tampering but does not prevent relay; channel binding does.
Defaults by version
From the Microsoft Learn LDAP signing and channel binding pages (both last updated 2 October 2026):
| Windows Server 2022 or earlier | Windows Server 2025 or later, new AD deployment | |
|---|---|---|
| Server signing | Optional: DCs accept signed and unsigned binds | Required by default, through the policy "Domain controller: LDAP server signing requirements enforcement", which takes precedence over the older signing-level policy |
Channel binding policy (LdapEnforceChannelBinding) |
Never (0) | When supported (1) |
| Channel binding auditing | Depends on update level (see below); 3074/3075 need the Server 2022 August 2023 or Server 2019 October 2023 update, policy 1 or 2, and diagnostic level 2 | Enabled by default |
| Windows client signing | Clients request signing by default but can fall back to unsigned | 2025 clients and Windows 11 24H2 encrypt LDAP by default |
The Microsoft sources disagree on when channel binding auditing arrived. The channel binding overview says Windows updates from March 2023 enabled CBT auditing by default on Server 2022 and 2019. KB4520412 dates the 3074/3075 audit events to the August 2023 update (Server 2022) and October 2023 update (Server 2019), and says a manual enablement step was needed until the November 14, 2023 update (2022) and January 9, 2024 update (2019). Plan on the KB's dates: keep DCs on current supported updates and confirm that 3074/3075 can appear before reading their absence as a clean result. Neither page promises 3074/3075 on Windows Server 2016, so do not rely on them there.
On upgrade to Windows Server 2025, Microsoft states that existing signing policies are preserved. If no server signing policy exists, the 2025 DC requires signing by default. That is a reason to define the policy explicitly in the Default Domain Controllers Policy before the first 2025 DC arrives, whichever value you choose.
Channel binding values: 0 Never (no validation); 1 When supported (clients that support CBT must provide it, others are allowed, audit events logged); 2 Always (all TLS + SASL clients must provide a valid CBT).
The events
All in Applications and Services Logs > Directory Service on each DC.
| Event | Meaning | Needs diagnostic level |
|---|---|---|
| 2886 | At startup: the DC does not reject unsigned SASL or clear-text simple binds | 0 |
| 2887 | 24-hour summary: unsigned SASL and clear-text simple binds the DC allowed | 0 |
| 2888 | 24-hour summary: such binds the DC rejected (signing enforced) | 0 |
| 2889 | Per client: IP address and identity of each unsigned or clear-text bind | 16 LDAP Interface Events = 2 |
| 3039 | Per client: LDAP bind over TLS that failed CBT validation | 2; only when CBT policy is 1 or 2 |
| 3040 | 24-hour summary of completed, unprotected LDAPS binds | 0; when CBT policy is Never |
| 3041 | Reminder to enforce CBT | 0; when CBT policy is Never |
| 3074 | Per client: bind over TLS that would fail CBT under enforcement | 2; policy 1 or 2; Server 2022 August 2023 or Server 2019 October 2023 update or later |
| 3075 | Per client: bind over TLS without channel binding information; logs IP, identity, whether the client supports CBT | as 3074 |
The diagnostic setting is the registry value 16 LDAP Interface Events under HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics. Microsoft says to set it to 2 (Basic) to capture 2889 and to set it back to 0 after the investigation to avoid a performance impact.
Read-only checks
None of these was run for this article. Steps 1–3 read logs and policy on domain controllers and need an account that can read the Directory Service log (administrative rights on the DC or delegated Event Log Readers). Step 4 is a temporary diagnostic change, listed separately because it modifies the registry.
1. Check how each DC is configured today.
Get-ADDomainController -Filter * | Select-Object HostName, OperatingSystem
gpresult /scope computer /h C:\Temp\dc-gpresult.html
Run gpresult on a DC to see which LDAP signing and channel binding policies apply, and from which GPO. Read-only apart from writing the report file. Note any DC on Windows Server 2025 and whether the signing enforcement policy is defined.
2. Read the 24-hour summaries on every DC.
$since = (Get-Date).AddDays(-7)
foreach ($dc in (Get-ADDomainController -Filter *).HostName) {
# Reset per DC so no value carries over from the previous DC
$oldest = $null; $logStarts = $null; $retention = $null; $found = $null
# Query 1: retention (when this DC's log starts)
try {
$oldest = Get-WinEvent -ComputerName $dc -LogName 'Directory Service' -Oldest -MaxEvents 1 -ErrorAction Stop
$logStarts = $oldest.TimeCreated
if ($logStarts -le $since) { $retention = 'Log covers the window' }
else { $retention = 'UNKNOWN: log starts after the window began' }
} catch {
$retention = "UNKNOWN: log start not established ($($_.Exception.Message))"
}
# Query 2: the filtered summaries
try {
$found = Get-WinEvent -ComputerName $dc -FilterHashtable @{LogName='Directory Service'; Id=2887,2888,3040; StartTime=$since} -ErrorAction Stop
$found | Select-Object @{n='DC';e={$dc}}, @{n='LogStarts';e={$logStarts}}, @{n='Retention';e={$retention}}, TimeCreated, Id, Message
} catch {
if ($_.FullyQualifiedErrorId -like 'NoMatchingEventsFound*') {
[pscustomobject]@{DC=$dc; LogStarts=$logStarts; Retention=$retention; Result="Filtered query succeeded: no 2887/2888/3040 since $since"}
} else {
[pscustomobject]@{DC=$dc; LogStarts=$logStarts; Retention=$retention; Result="FILTERED QUERY FAILED: $($_.Exception.Message)"}
}
}
}
Read-only. The script runs two separate queries per DC and resets its variables for each DC. The first establishes when the log starts. The second reads the summaries. The output gives the events found, a filtered query that succeeded with no match, or a failed filtered query, each with that DC's own retention result. A filtered no-match counts as "none found" only when the retention result says the log covers the window. If the retention query failed or returned nothing (an empty log also ends up there), or the log starts after the window began, that DC is unknown, not clean. The same applies when the filtered query failed. Read an unknown DC locally or fix access before going on. 2887 gives counts of simple binds without SSL/TLS and unsigned SASL binds. Only if every DC was read successfully, every log covers the window, and 2887 is absent across several days of normal business (including month-end jobs, with the usual LDAP-dependent applications known to have run), is signing enforcement low risk. Do not conclude that from one day. Remote event log access depends on firewall rules.
3. Check for channel binding audit events already present.
Query 3039, 3074 and 3075 the same way, recording per-DC query success. These events are generated only when the channel binding policy is When supported (1) or Always (2), and 3074/3075 also need the update levels above and diagnostic level 2. If your policy is Never (0), 3039/3074/3075 are not generated; 3040 counts unprotected LDAPS binds instead. No 3074/3075 under policy 0, or without diagnostic level 2, means nothing about client compatibility.
4. Temporary diagnostic change: identify each client (2889, 3074, 3075).
This is a change, not a read: it raises a diagnostic level that increases logging on the DC.
reg query "HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics" /v "16 LDAP Interface Events"
reg add "HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics" /v "16 LDAP Interface Events" /t REG_DWORD /d 2 /f
Record the current value first (the reg query line). Make the change on one DC at a time, in agreement with whoever owns DC performance, and for a defined window (for example one business week, including the scheduled jobs that run on a particular day).
- Verification: 2889 events appear in the Directory Service log with client IP and account.
- Rollback: set the value back to the recorded original (normally 0) with the same
reg addand/d 0. Microsoft's guidance is to return it to 0 after the investigation.
Collect the events into a list:
Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2889,3074,3075} |
Select-Object TimeCreated, Id, @{n='Detail';e={$_.Message -replace '\s+',' '}} |
Export-Csv C:\Temp\ldap-clients.csv -NoTypeInformation
Read-only apart from the CSV. Deduplicate by IP and account, then resolve each IP to a host and an owner.
Interpreting the results
| Finding | Meaning | Action |
|---|---|---|
| 2889 from a printer, scanner, NAS or firewall with a service account | Unsigned SASL or simple bind over port 389 without TLS; the device type does not tell you which, so read the event detail and the device's LDAP settings | Reconfigure the device for LDAPS (636) or STARTTLS with certificate validation, or for signed SASL if supported; get the owner's agreement |
| 2889 from a Windows server running an application | The application or its library does a simple or unsigned bind | Change the application's LDAP setting to secure LDAP or signed SASL; check the vendor's documentation |
| 2889 from Windows clients themselves | Unusual: Windows requests signing by default | Check the client signing policy ("Network security: LDAP client signing requirements" set to None?) |
| 3075 from a client over LDAPS, "supports CBT" false | Client can't do channel binding | Simple binds aren't affected by CBT; for SASL clients, update the client or library before "Always" |
| 3039 | A bind over TLS failed CBT validation: improperly formatted CBT, a CBT-capable client that sent none, or CBT required and not provided | Read the event detail for the client and reason; update or reconfigure the client before "Always" |
| 3074 | A bind over TLS would fail CBT validation under enforcement | Client or library update needed; enforcement would break it |
| Every DC read successfully, logs cover a full business cycle, no 2887; policy 1 or 2 and diagnostic level 2 in place, no 3074/3075 | No known non-compliant clients in that window | Proceed to enforcement plan, keeping the inventory open |
| Any DC unreadable, or a log that does not cover the window | Unknown for that DC | Do not proceed until it is read |
| 2888 rejected counts after enforcement | Clients now being refused | Expected during rollout if unaddressed clients remain; review the list |
The 2889 event shows the account a device used. Treat that as a lead, not the owner. A shared "ldapbind" account used by fifteen devices needs fifteen conversations. Inventory the account's uses before changing its password or disabling it.
Decision guidance
Order of changes
- Define the policies explicitly in the Default Domain Controllers Policy (or your DC baseline GPO) at their current effective values. That makes a later Windows Server 2025 DC behave predictably on upgrade. Verification:
gpresulton each DC shows the policy and source GPO. Rollback: remove the definition from the GPO. - Fix clients from the audit list, one owner at a time. Prefer LDAPS or STARTTLS with proper certificate validation for appliances that can only do simple binds; prefer Kerberos SASL for software that supports it. Verification: a real LDAP-dependent operation on that client (a sign-in, a lookup, a scan-to-email) succeeds, and its IP stops appearing in 2889. An IP that disappears from 2889 may also have stopped connecting, so absence alone is not proof. Rollback: the client's previous LDAP setting, recorded before the change.
- Enforce signing: "Domain controller: LDAP server signing requirements" = Require signing (and, on 2025, the enforcement policy enabled). Microsoft notes the change applies at the next Group Policy refresh, or
gpupdate /forceon the DCs. Plan it for a window with owners of remaining clients on hand. - Verification:gpresulton each DC shows the policy in effect, the known LDAP-dependent applications still work, and Microsoft's production check, event 2888 (rejected binds) every 24 hours, shows no rejections from expected clients. Rising 2888 counts mean clients are still trying unsigned binds. Microsoft's LDP.exe simple-bind test ("Strong Authentication Required") sends credentials without TLS, so Microsoft restricts it to an isolated lab with a disposable non-privileged account. Do not run it in production. - Rollback: set the policy back to None (and the enforcement policy to Disabled on 2025) and refresh policy. Clients reconnect on their next bind attempt. - Set channel binding to "When supported" (1) if it is still Never. This is enforcement, not just logging: clients that support CBT must now provide it. Plan it like step 3, then collect 3039/3074/3075 for a further cycle with diagnostic level 2. Verification:
gpresultshows the policy in effect, LDAPS-dependent applications still bind, and 3039 shows no failures from expected clients. Rollback: back to 0 and refresh policy. - Set channel binding to "Always" (2) only when 3074/3075 lists are empty on every DC that was read successfully with the prerequisites in place, or every remaining client is accepted as broken. Verification: LDAPS-dependent applications still bind and no 3039 failures from expected clients. Rollback: back to 1.
Do the DCs in a controlled order if your GPO structure allows it. Each DC applies policy independently, so a staged rollout limits the blast radius and shows problems early.
Clients and AD LDS
Windows clients follow "Network security: LDAP client signing requirements". Microsoft recommends Negotiate signing for gradual deployment and Require signing for maximum security. Move clients to Require signing on a pilot group first, and only after the DC side is settled.
AD LDS instances are configured separately, through the LDAPServerIntegrity value under the instance's Parameters key (0 disables signing and is the default; 2 requires signing). Audit their clients the same way.
What not to do
- Do not enforce first and "see what breaks". Owners of appliances are often outside IT and take weeks to respond.
- Do not leave
16 LDAP Interface Eventsat 2 indefinitely. Microsoft calls out a performance impact; set it back. - Do not "fix" an appliance by moving it to an unvalidated LDAPS connection (certificate checks off). It moves the risk from tampering to impersonation.
- Do not run the LDP simple-bind test with real credentials on a production network. Microsoft restricts it to an isolated lab and a disposable account.
- Do not change a shared bind account's password to "find out who uses it". That causes an outage, and possibly lockouts, instead of an inventory.
- Do not treat LDAPS as covered by signing enforcement. Signing does not apply on TLS; channel binding is the relevant control there.
Limitations
- The audit only sees binds that happen during the window. Quarterly jobs, DR tests and seldom-used appliances can be missed; keep the inventory open after enforcement.
- 2889 shows an IP and identity; NAT, proxies and load balancers in front of DCs can hide the real client.
- Third-party client settings (printers, firewalls, Linux SSSD, Java applications) are product-specific and not covered.
- The Microsoft Learn pages and KB4520412 describe current defaults; future Windows updates may change them. Re-check before each phase.
- Channel binding event meanings (3039–3041, 3074–3075) are taken from the current Microsoft Learn channel binding page; check your DC's event text if it differs.
Acceptance checklist
- [ ] Every DC's operating system and effective signing and channel binding policy recorded, including any Windows Server 2025 DC.
- [ ] Signing and CBT policies are explicitly defined in the DC GPO before any change.
- [ ] 2887/3040 summaries reviewed on every DC over a representative period, with each DC's query success and log start date recorded; no DC left unknown.
- [ ] Diagnostic level raised temporarily, 2889/3074/3075 collected, level returned to its original value.
- [ ] Every client IP resolved to a host, owner and fix; shared bind accounts inventoried.
- [ ] Each fixed client verified by a successful real LDAP-dependent operation after the change (a sign-in, a lookup, a scan-to-email), with the policy in effect confirmed by
gpresultand no matching 2889, 2888, 3039 or 3074 events for that client. A client that simply stopped appearing in 2889 does not count as fixed. - [ ] Signing enforced in a planned window; 2888 monitored; rollback written down.
- [ ] Channel binding moved 0 → 1 → 2 with audit cycles between; rollback written down.
- [ ] AD LDS instances handled separately.
References
All accessed 2 November 2026.
- Microsoft Learn, "LDAP signing for Active Directory Domain Services on Windows Server" (last updated 2026-10-02): https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/ldap-signing
- Microsoft Learn, "LDAP channel binding in Active Directory" (last updated 2026-10-02): https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/ldap-channel-binding
- Microsoft Learn, "Configure LDAP signing by using Group Policy" (last updated 2026-10-02): https://learn.microsoft.com/en-us/windows-server/identity/manage-ldap-signing-group-policy
- Microsoft Support, KB4520412, "2020, 2023, and 2024 LDAP channel binding and LDAP signing requirements for Windows": https://support.microsoft.com/en-us/topic/2020-2023-and-2024-ldap-channel-binding-and-ldap-signing-requirements-for-windows-kb4520412-ef185fb8-00f7-167d-744c-f299a66fc00a
Related articles
- Group Policy Not Applying: gpresult, Events and SYSVOL
- How to harden VMware without breaking operations or recovery
-
Before Restricting NTLM: Inventory Who Uses It and Why Kerberos Was Not Used
- Account Keeps Locking Out: Find the Source From Event 4740 to the Process
Learning notes
- Signing protects non-TLS SASL sessions and, when required, rejects simple binds without TLS; channel binding protects SASL over TLS against relay.
- Event 2887 tells you whether there is a problem; 2889 (diagnostic level 2) tells you who.
- Windows Server 2025 changes the defaults: signing required on new deployments, CBT "When supported" with auditing.
- Define the policies explicitly before a 2025 DC arrives, so upgrades do not change behaviour unexpectedly.
- Enforce in stages, with successful real LDAP operations, 2888 and 3039/3074/3075 as the evidence and a written rollback at each stage. Missing events prove nothing unless the DC was read and the logging prerequisites were met.