1. Double Decryption: The Most Common Cause
This bug tripped me up the first time too. The error CRYPT_E_ALREADY_DECRYPTED (0X80091009) pops up when your code or app calls CryptDecryptMessage (or its Crypt32.dll equivalent) on a message that's already been decrypted. Windows cryptography APIs don't handle this gracefully—they throw this exact error.
You'll see this most often in:
- Custom software that processes S/MIME emails and accidentally decrypts the same message twice.
- Scripts that loop through a message store and re-process decrypted content.
- Outlook add-ins that hook into the decryption pipeline and trigger it again.
The Fix
Check whether the message has already been decrypted before calling CryptDecryptMessage. In C/C++, look for the CMSG_ENVELOPED_ALGORITHM_PROP property. If it's present, the message was already processed.
// Pseudo-code example
BOOL isDecrypted = CryptMsgGetParam(hMsg, CMSG_ENVELOPED_ALGORITHM_PROP, 0, NULL, &dwSize);
if (isDecrypted) {
// Already decrypted — skip or return the existing plaintext
return S_OK;
}
// Otherwise, proceed with decryption
In .NET and PowerShell, wrap your call in a try-catch and check the CryptographicException’s ErrorCode property. If it matches 0x80091009, you know it’s a double decryption.
If you're using a third-party library like MimeKit or BouncyCastle, make sure you're not caching decrypted data and then trying to decrypt the original stream again. I've seen this happen in email clients that do a pre-validation pass.
2. S/MIME Message Processing in Outlook or Mail Apps
When you open a signed and encrypted email in Outlook (2016, 2019, or Microsoft 365), the client auto-decrypts it. If a plugin or another process—like an archiver or a security scanner—tries to decrypt the same message again, you get CRYPT_E_ALREADY_DECRYPTED. This is especially common with Exchange Online and third-party email security gateways that tamper with the message.
Reproduce This
Open an encrypted email in Outlook while a script runs an Execute method on the same MailItem. Boom—error appears in the log or as a dialog.
The Fix
Disable any add-ins that touch S/MIME decryption. Go to File > Options > Add-ins. Disable third-party security or archiving add-ins one by one. Restart Outlook each time.
If that doesn't work, check the Windows Event Log under Applications and Services Logs > Microsoft > Windows > CryptoAPI. Look for Event ID 13 (decryption failure). The details will tell you which process is double-dipping.
Another workaround: save the email as a .msg file, then decrypt offline. That isolates the process from the real-time decryption pipeline. Not elegant, but it works for auditing.
3. Corrupt Registry or Certificate Store
This one's rare but nasty. A corrupt registry entry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider can cause the Cryptographic Service Provider (CSP) to misreport decryption status. The result: your app thinks the message is already decrypted when it's not, throwing 0x80091009.
Fix It
- Open
regedit.exeas Administrator. - Go to
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider. - Look for a key named Microsoft Base Cryptographic Provider v1.0 (or similar). Right-click and export it as a backup.
- Delete that key, then reinstall the provider via Control Panel > Programs > Turn Windows features on or off → check Windows Process Activation Service → apply.
- Reboot and test.
Alternatively, run this PowerShell command to repair the certificate store without touching the registry manually:
certutil -repairstore MY
This rebuilds the local machine personal store. It's safe—doesn't wipe certificates.
Quick-Reference Summary
| Cause | Diagnosis | Fix |
|---|---|---|
| Double decryption in code | Error occurs on a specific API call | Check decrypted state before calling CryptDecryptMessage |
| S/MIME double processing | Outlook add-in or email scanner | Disable add-ins; check Event ID 13 |
| Corrupt registry/CSP | Error across multiple apps | Repair provider via registry or certutil |