dotnet/wpf · error · ArgumentException
Cannot perform stream operation because CryptoProvider is…
Error message
Cannot perform stream operation because CryptoProvider is not set to allow decryption.
What it means
The RightsManagementEncryptedStream constructor requires a CryptoProvider whose CanDecrypt property is true, because the stream's purpose is to transparently decrypt an encrypted compound-file substream. If the provider's use rights do not permit decryption, construction fails immediately with ArgumentException naming the cryptoProvider parameter.
Solutions
- Check cryptoProvider.CanDecrypt before constructing the stream and surface a user-facing rights message instead of constructing.
- Request/obtain a use license with decryption rights (re-acquire the license from the rights management server, or fix the publishing policy to grant Read/Decrypt to the user).
- Ensure the SecureEnvironment/user account used to create the CryptoProvider is the intended, licensed user.
- In tests/dev, publish the content with rights that include decryption for the test identity.
Example fix
// before
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);
// after
if (!cryptoProvider.CanDecrypt)
throw new InvalidOperationException("Current use license does not permit decryption.");
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); Defensive patterns
Strategy: validation
Validate before calling
if (cryptoProvider == null)
throw new ArgumentNullException(nameof(cryptoProvider));
if (!cryptoProvider.CanDecrypt)
throw new InvalidOperationException("License does not grant decryption rights.");
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); Type guard
bool CanUseForDecryption(System.Security.RightsManagement.CryptoProvider p)
=> p != null && p.CanDecrypt; Try / catch
try { stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); }
catch (ArgumentException ex) when (ex.ParamName == "cryptoProvider")
{ /* surface rights error, prompt user to re-acquire license */ } Prevention
- Always check CanDecrypt (and CanMergeBlocks) before constructing the stream.
- Validate the use license grants Read/Decrypt for the current user before opening.
- Handle expired/revoked licenses by re-acquiring from the RM server.
- Distinguish encryption-only providers from decryption-capable ones in your provider factory.
When it happens
Trigger: Constructing RightsManagementEncryptedStream(baseStream, cryptoProvider) where cryptoProvider.CanDecrypt == false — typically because the user was granted rights that exclude decryption (e.g. view-only grant, expired or revoked use license).
Common situations: Opening a rights-managed XPS/compound document under a license lacking DECRYPT rights; using a CryptoProvider created for encryption-only workflows; testing with an unsigned/expired use license in an RM environment.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- SR.CryptoProviderCanNotMergeBlocks
- SR.CannotChangeCryptoProvider
- SR.CryptoProviderIsNotReady
- SR.RightsManagementExceptionNoRightsForOperation
- SR.RMProviderExceptionNoRightsToDocument
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/150600246745579f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptedStream.cs:281
base.Dispose(disposing);
}
}
//------------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
internal RightsManagementEncryptedStream(
Stream baseStream,
CryptoProvider cryptoProvider)
{
Debug.Assert(baseStream != null);
Debug.Assert(cryptoProvider != null);
if (!cryptoProvider.CanDecrypt )
{
throw new ArgumentException(SR.CryptoProviderCanNotDecrypt, nameof(cryptoProvider));
}
if (!cryptoProvider.CanMergeBlocks)
{
throw new ArgumentException(SR.CryptoProviderCanNotMergeBlocks, nameof(cryptoProvider));
}
_baseStream = baseStream;
_cryptoProvider = cryptoProvider;
// Currently BitConverter is implemented as only supporting Little Endian byte order
// regardless of the machine type. We would like to make sure that this doesn't change
// as we need Little Endian byte order decoding capability on all machines in order to
// parse files that travel across different machine types.
Debug.Assert(BitConverter.IsLittleEndian);
// initialize stream length
ParseStreamLength();View on GitHub (pinned to 81131a70a4)