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

  1. Check cryptoProvider.CanDecrypt before constructing the stream and surface a user-facing rights message instead of constructing.
  2. 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).
  3. Ensure the SecureEnvironment/user account used to create the CryptoProvider is the intended, licensed user.
  4. 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

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


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)