dotnet/wpf · error · ArgumentException
SR.CryptoProviderCanNotMergeBlocks
Error message
SR.CryptoProviderCanNotMergeBlocks
What it means
The constructor also requires cryptoProvider.CanMergeBlocks to be true: this stream's decryption algorithm assumes the CryptoProvider can correctly handle block merging during transform. A provider that cannot merge blocks cannot satisfy the block-size invariants this stream implementation relies on, so ArgumentException (SR.CryptoProviderCanNotMergeBlocks) is thrown for the cryptoProvider parameter.
Solutions
- Check cryptoProvider.CanMergeBlocks before construction and choose an alternate provider that supports block merging.
- Re-acquire the use license / CryptoProvider from the same rights-management implementation that published the content so block sizes match.
- Update the RM SDK/environment to a version whose providers support CanMergeBlocks for this content.
- Do not attempt to work around by wrapping the provider; the invariant is required by the stream's block math.
Example fix
// before
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);
// after
if (!cryptoProvider.CanMergeBlocks)
throw new InvalidOperationException("CryptoProvider cannot merge blocks; incompatible provider.");
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); Defensive patterns
Strategy: validation
Validate before calling
if (cryptoProvider == null)
throw new ArgumentNullException(nameof(cryptoProvider));
if (!cryptoProvider.CanMergeBlocks)
throw new InvalidOperationException("CryptoProvider lacks block-merge support.");
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); Type guard
bool CanUseForEncryptedStream(System.Security.RightsManagement.CryptoProvider p)
=> p != null && p.CanDecrypt && p.CanMergeBlocks; Try / catch
try { stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); }
catch (ArgumentException ex) when (ex.ParamName == "cryptoProvider")
{ /* swap to a merge-capable provider or report incompatibility */ } Prevention
- Gate construction on CanDecrypt && CanMergeBlocks in a single guard.
- Acquire CryptoProvider from the same RM implementation/SDK that published the content.
- Avoid mixing providers across RM SDK versions.
- Fail fast with a clear message instead of attempting block-level workarounds.
When it happens
Trigger: Constructing RightsManagementEncryptedStream(baseStream, cryptoProvider) where cryptoProvider.CanMergeBlocks == false — i.e. the provider's block granularity is incompatible with the encrypted stream's block layout.
Common situations: Using a CryptoProvider obtained from a rights-management implementation whose content key/block size differs from what the packaging layer expects; mixing crypto providers across implementations or versions where block-merge support is absent.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Cannot perform stream operation because CryptoProvider is…
- SR.CannotChangeCryptoProvider
- SR.CryptoProviderIsNotReady
- ArgumentException(SR.Format(SR.CollectionCannotContainNulls…
- ArgumentException(SR.StringIsNullOrEmpty, nameof(fileName))
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/295e2556429fa2ec.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptedStream.cs:286
//
// 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();
}
//------------------------------------------------------
//
// Private MethodsView on GitHub (pinned to 81131a70a4)