{"record":{"id":"150600246745579f","repo":"dotnet/wpf","slug":"cannot-perform-stream-operation-because-cryptoprovider-is","errorCode":null,"errorMessage":"Cannot perform stream operation because CryptoProvider is not set to allow decryption.","messagePattern":"Cannot perform stream operation because CryptoProvider is not set to allow decryption\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptedStream.cs","lineNumber":281,"sourceCode":"                base.Dispose(disposing);\n            }\n        }\n\n        //------------------------------------------------------\n        //\n        //  Internal Methods\n        //\n        //------------------------------------------------------\n        internal RightsManagementEncryptedStream(\n                                        Stream baseStream,\n                                        CryptoProvider cryptoProvider)\n        {\n            Debug.Assert(baseStream != null);\n            Debug.Assert(cryptoProvider != null);\n\n            if (!cryptoProvider.CanDecrypt )\n            {\n                throw new ArgumentException(SR.CryptoProviderCanNotDecrypt, nameof(cryptoProvider));            \n            }\n\n            if (!cryptoProvider.CanMergeBlocks)\n            {\n                throw new ArgumentException(SR.CryptoProviderCanNotMergeBlocks, nameof(cryptoProvider));            \n            }\n            \n            _baseStream = baseStream;\n            _cryptoProvider = cryptoProvider;\n\n            // Currently BitConverter is implemented as only supporting Little Endian byte order    \n            // regardless of the machine type. We would like to make sure that this doesn't change \n            // as we need Little Endian byte order decoding capability on all machines in order to \n            // parse files that travel across different machine types.\n            Debug.Assert(BitConverter.IsLittleEndian);\n\n            // initialize stream length\n            ParseStreamLength();","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptedStream.cs#L263-L299","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nvar stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);\n// after\nif (!cryptoProvider.CanDecrypt)\n    throw new InvalidOperationException(\"Current use license does not permit decryption.\");\nvar stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);","handlingStrategy":"validation","validationCode":"if (cryptoProvider == null)\n    throw new ArgumentNullException(nameof(cryptoProvider));\nif (!cryptoProvider.CanDecrypt)\n    throw new InvalidOperationException(\"License does not grant decryption rights.\");\nvar stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);","typeGuard":"bool CanUseForDecryption(System.Security.RightsManagement.CryptoProvider p)\n    => p != null && p.CanDecrypt;","tryCatchPattern":"try { stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); }\ncatch (ArgumentException ex) when (ex.ParamName == \"cryptoProvider\")\n{ /* surface rights error, prompt user to re-acquire license */ }","preventionTips":["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."],"tags":["rights-management","crypto","argumentexception","permissions"],"backgroundTag":"permission-denied","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}