Had a client last month whose sign tool started spitting out NTE_BAD_KEYSET_PARAM (0x8009001F) out of nowhere. Nothing changed on the dev box, or so they said. Turns out Windows Update had touched the profile permissions on their Crypto\RSA folder and locked them out of their own keys. That's the pattern with this error. The keyset exists, Windows just can't validate the parameters pointing at it.
You'll see 0x8009001F when a CryptoAPI (or CNG) call hits a keyset whose parameters don't match what's actually on disk, or when the caller doesn't have permission to read the key container. It shows up in signing tools, EFS cert operations, DPAPI-backed apps, and anything using CryptAcquireContext. The fix depends on which of three things is broken.
1. Corrupted or missing keys in the user profile (most common)
This is the one I see 80% of the time. The user's %APPDATA%\Microsoft\Crypto\RSA folder gets wiped, has the wrong ACL, or the key container references a file that isn't there anymore. The keyset parameter (the container name) is valid, but the backing file isn't. Windows returns 0x8009001F because it can't reconcile the two.
First, confirm it's profile-scoped. Log in as a different user on the same box and try the same operation. If it works, it's the profile.
Then check the folder permissions:
icacls "%APPDATA%\Microsoft\Crypto\RSA"
You should see the current user with Full Control, SYSTEM with Full Control, and Administrators with Full Control. Nothing else. If the current user is missing or only has Read, that's your bug. Fix it with:
icacls "%APPDATA%\Microsoft\Crypto\RSA" /reset /T /C
takeown /f "%APPDATA%\Microsoft\Crypto\RSA" /r /d y
icacls "%APPDATA%\Microsoft\Crypto\RSA" /grant "%USERNAME%":(F) /T
Re-run the failing operation. If it's still broken, the key file itself is toast. Rename the RSA folder to RSA.old and let Windows rebuild it. You'll lose any keys stored only in the user profile, so export anything you can first via certmgr.msc.
If you're on a roaming profile or folder redirection, this gets uglier. The crypto folder shouldn't roam, and if it does, you get exactly this error after every sync. Remove it from the redirection scope.
2. CNG Key Isolation service is off or hung
Second most common. The KeyIso service (CNG Key Isolation) hosts key operations in a separate process for security. If it's stopped, disabled, or wedged, every key operation that needs it fails. I've seen this after a botched patch cycle more than once.
Check it:
sc query KeyIso
If it's not RUNNING, start it:
sc config KeyIso start= demand
net start KeyIso
If it's stuck in STOP_PENDING, kill the process tree and restart. On a hung machine I've also had to bounce CryptSvc too:
net stop CryptSvc
net start CryptSvc
Don't disable KeyIso. Some old hardening guides told people to. That advice was wrong then and it's wrong now. It breaks certificate services, EFS, and anything using DPAPI.
Also check the event log for KeyIso crashes. If it's crashing repeatedly, the cause is usually a bad third-party CSP (smart card middleware is the usual suspect). Uninstall it, reboot, and retest.
3. Machine-level keyset with bad ACLs or a stale container name
Less common but nastier. This is when the keyset lives under %ProgramData%\Microsoft\Crypto\RSA\MachineKeys or the machine key container referenced by an app has a name that no longer matches the file on disk. Services running as NetworkService or LocalSystem hit this a lot.
Check the machine keys folder:
dir "%ProgramData%\Microsoft\Crypto\RSA\MachineKeys"
Default ACLs there should grant Everyone Read and Special Permissions (this is one of the few places where a broad ACL is correct). If someone tightened it, keys can't be read and you get 0x8009001F. Reset with:
icacls "%ProgramData%\Microsoft\Crypto\RSA\MachineKeys" /reset /T /C
If a specific service is failing, find its container name in the app's config, then check the corresponding file exists in MachineKeys. Stale names happen after an app upgrade that changes the container but doesn't clean up the old one. Delete the orphaned file and let the app recreate it.
One more gotcha: if the app runs under a service account that you've recently changed from LocalSystem to a domain user, the key container is now in the wrong scope. You either move the key or re-run the app's keygen under the new identity. There's no clean way to convert them in place.
Quick reference
| Symptom | Likely cause | First fix to try |
|---|---|---|
| Error only for one user, works for others | Corrupted profile crypto folder | Reset ACLs on %APPDATA%\Microsoft\Crypto\RSA |
| Error for all users on the box | KeyIso or CryptSvc stopped | sc config KeyIso start= demand && net start KeyIso |
| Error only for a service or scheduled task | Machine keyset ACL or stale container | Reset ACLs on MachineKeys, remove orphan container file |
| Error appears after profile roaming/sync | Crypto folder is being redirected | Remove it from redirection scope |
| Error repeats after reboot | Bad third-party CSP (smart card middleware) | Uninstall the CSP, reboot, retest |
| Error follows a service account change | Key container in wrong identity scope | Re-run the app's keygen under the new account |
Don't bother with DISM or SFC for this one. They won't touch user crypto folders and they won't fix a service that's stopped. Start with the profile check, then the service, then the machine keys. That order matches reality about 95% of the time.