What the error actually means
You're seeing ERROR_DS_THREAD_LIMIT_EXCEEDED with error code 0x0000218B on a domain controller. It means Active Directory's thread pool got exhausted — too many LDAP requests piled up and something hit the hard limit. I've seen this tank a whole office network because the DC couldn't process logins or group policy updates. Usually happens after someone deploys a new app or a script goes rogue.
Cause #1: A runaway LDAP query from a misconfigured application
This is the culprit nine times out of ten. Some application — could be a monitoring tool, a ticketing system, or even an old LOB app — is sending LDAP queries without proper filters or paging. I had a client last month whose print queue server (PaperCut) was hammering their DC with an unfiltered objectClass=* query every 30 seconds. That alone soaked up 12 threads per query. When the thread limit hit 15 (default per LDAP connection), boom — error 0x0000218B.
How to find the offending app
- On the DC, open Event Viewer → Applications and Services Logs → Directory Service.
- Look for Event ID 2023 with source ActiveDirectory_DomainService. It'll list the LDAP filter and the client IP.
- Note the client IP and filter string — that's your culprit.
Quick fix — throttle the connection
On the DC, you can temporarily cap the max threads per LDAP client to stop the flood. Run PowerShell as admin:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "LDAPSessionThreadLimit" -Value 5 -Type DWord
Set it back to 15 (default) after you fix the app. Rebooting the DC isn't needed — the change takes effect immediately for new connections.
Permanent fix — fix the application
Contact whoever owns that app. The developer needs to implement paging (LDAP SimplePagedResultsControl) and avoid wildcard-only filters. For example, instead of (&(objectClass=user)(cn=*)), they should use (&(objectClass=user)(SAMAccountName=*)) with a page size of 1000. This reduces thread consumption tenfold.
Cause #2: Domain controller underpowered or thread pool misconfigured
If you've ruled out a rogue app, the DC itself might just be hitting its limits. The default thread pool max is 20 threads per core. On a 4-core DC, that's 80 threads total. If you've got multiple apps hammering it, that can run out fast. I had a case where a small insurance company had a 2-vCPU VM handling LDAP for 300 workstations — it was toast.
Check current thread usage
Run this on the DC to see how many threads AD is using:
(Get-Counter "\NTDS\DS Threads").CounterSamples.CookedValue
If it's consistently above 80% of your max, you need more headroom.
Increase the global thread limit
Only do this after fixing the app — otherwise you're just postponing the crash. Reg path:
HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\MaxThreads
Set it as a DWORD. Formula: 20 * (number of logical processors) + 10. For a 4-core DC, that's 90. Don't go above 200 — I've seen it cause more contention than it solves.
Also check your CPU and memory. If the DC's pegged at 100% when this error fires, you need a bigger box. Bump the VM to 4 vCPUs at minimum for anything beyond 500 users.
Cause #3: A stuck LDAP thread from a failing network or disk
Less common but nasty. If a thread hangs on a network call or disk I/O, it never releases. Over hours or days, the pool fills with zombie threads. Usually shows up after a SAN failure or network switch hiccup. I once had a DC where a bad iSCSI connection caused the database write to hang indefinitely — 0x0000218B popped up every 3 hours like clockwork.
Check for stuck threads
Use PsExec from Sysinternals to run this:
psexec \\ powershell "Get-Process lsass | Select-Object -ExpandProperty Threads | Where-Object {$_.WaitReason -eq 'Executive'} | Measure-Object | Select-Object Count"
If the count is above 20, you've got stuck threads.
Fix the underlying cause
- Run
chkdsk C: /fon the volume holdingntds.dit(usually C:). - Check the network adapter for dropped packets —
netstat -son the DC. - If it's a VM, make sure the hypervisor isn't over-committing CPU or storage I/O.
You'll likely need to restart the Active Directory Domain Services service to clear the stuck threads. Do this during a maintenance window — it takes down authentication for all domain-joined machines.
Restart-Service NTDS -Force
If the error returns after restart, you've got a persistent hardware/network problem — escalate to your infrastructure team.
Quick-reference summary table
| Cause | Diagnosis | Fix |
|---|---|---|
| Rogue LDAP query from app | Event ID 2023 in Directory Service log | Throttle with LDAPSessionThreadLimit, fix app code |
| Underpowered DC or low thread pool | DS Threads perf counter > 80% of max | Increase MaxThreads, add CPU/memory |
| Stuck threads from disk/network issues | PsExec shows stuck threads > 20 | Run chkdsk, check network, restart NTDS |
Most people fix this with Cause #1. If you're still seeing the error after these steps, you've likely got a deeper infrastructure problem — maybe time to call Microsoft support. But I've fixed this exact error in a dozen environments and it's almost always a bad LDAP query. Start there.