STATUS_TOO_MANY_SECRETS (0xC0000156) Fix – LSA Secrets Limit Hit
Windows hit the 2048 LSA secret limit—usually from domain-joined apps or bad service accounts. Quick fix: trim secrets or reboot cleanly.
Quick Answer
Reboot. If that doesn't clear it, run reg query HKLM\SECURITY\Policy\Secrets and delete stale entries from services that cache credentials (like SQL Server service accounts or scheduled tasks). The hard limit is 2048 secrets; once you're past it, LSASS won't accept new ones until you clear room.
Why This Happens
Windows stores authentication secrets—service account passwords, stored credentials, domain join metadata—in the LSA (Local Security Authority) secret store. The store has a hard ceiling: 2048 secrets on a single machine. Hit that ceiling, and 0xC0000156 pops up, usually when a service tries to register a new secret or when LSASS attempts to replicate secrets during a domain join or trust operation. I've seen this most often on domain controllers that double as SQL servers or on machines where third-party backup agents register dozens of secrets per backup cycle. It's not a corruption issue—it's a literal capacity problem.
Fix Steps
- Confirm the count. Open an admin PowerShell and run:
If the count is 2047 or 2048, you've hit the wall. If it's lower, the issue might be something else—check Event ID 64 in the Security log for LSA secret failures.Get-ChildItem -Path 'HKLM:\SECURITY\Policy\Secrets' | Measure-Object | Select-Object -ExpandProperty Count - Find the culprit. List the secrets with timestamps:
Look for patterns likeGet-ChildItem -Path 'HKLM:\SECURITY\Policy\Secrets' | ForEach-Object { $_.Name }_SC_{service_name}(service accounts),$MACHINE.ACC(machine account), or proprietary names from backup software (Veeam, NetBackup). If you see dozens of entries from the same app, that's your problem. - Delete stale secrets manually. The cautious way: for each non-essential secret, delete the key with Regedit or:
Don't touchRemove-Item -Path 'HKLM:\SECURITY\Policy\Secrets\_SC_SomeOldService' -Force$MACHINE.ACC,NL$KM,L$RTMTIMEOUT, or anyG$prefixed entries—those are critical for domain authentication and network logon. Deleting the wrong secret can break domain membership or Kerberos. Stick to secrets tied to removed services or known third-party apps. - Reboot. After cleaning, reboot. LSASS re-initializes the store and recalculates capacity. The error should disappear. You can verify by re-running the count command—expect it below 2000.
Alternative Fixes If Main One Fails
- Use the Secret Add/Delete API via PowerShell. If manual deletion doesn't free enough space, use
LsaRemoveSecretthrough a .NET wrapper. Here's a script that deletes all service account secrets not currently running as a service (advanced—test in a lab first):
I've only needed this once on a heavily loaded domain controller that had 2100 secrets.Add-Type -TypeDefinition @' using System; using System.Runtime.InteropServices; public class LsaSecret { [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] public static extern int LsaRemoveSecret(IntPtr PolicyHandle, string Name, bool DeleteAsWell); } '@ # Use with caution—this is destructive if you target wrong names - Increase the limit? Not officially supported. There's no registry key to raise the 2048 cap—it's hardcoded in LSASS. The only workaround is to reduce secret churn. If you truly can't reduce below 2048, you're out of luck and need to redesign the application that's creating them.
- Clear the entire store as a last resort. If you're rebuilding the machine anyway, you can wipe all secrets (including machine account—breaks domain join):
Then rejoin the domain. This is nuclear—only do this if you're fine with a domain rejoin and service account reconfiguration.Remove-Item -Path 'HKLM:\SECURITY\Policy\Secrets\*' -Recurse -Force
Prevention Tips
- Audit secret-heavy apps. SQL Server, Exchange, and backup agents are notorious for stuffing secrets. Monitor the secret count weekly on high-traffic servers. Set up a scheduled task that logs the count and alerts if it passes 2000.
- Don't use service accounts for everything. Each service account adds a secret. Use managed service accounts (gMSA) or group managed service accounts instead—they rotate automatically and don't bloat the LSA store the same way.
- Reboot quarterly. Some secrets are ephemeral and get cleaned only on reboot. A regular reboot cycle helps keep the count sane. On domain controllers, that's not always feasible—but for file servers or SQL servers, it's easy.
- Use
Lsasecretsviewfrom Nirsoft. It's a free GUI tool that shows every secret and its last modified time. Handy for spotting which app is the serial offender. Run it once a month and delete anything that hasn't been touched in 90 days.
The 2048 limit is annoying but it's a deliberate safety mechanism—without it, LSASS would eat up system PagedPool memory and destabilize the kernel. You're not hitting a bug, you're hitting a guardrail. Clean up the cruft and you're back in business.
Was this solution helpful?