dotnet/wpf · error · System.ArgumentException
SR.HashAlgorithmMustBeReusable
Error message
SR.HashAlgorithmMustBeReusable
What it means
GenerateManifest validates that the hash algorithm passed in supports CanReuseTransform before signing. WPF package signing streams multiple parts through the same hash transform, so a non-reusable algorithm would silently produce wrong digests; the library rejects it up front with ArgumentException.
Solutions
- Use a standard reusable algorithm such as SHA256CryptoServiceProvider/SHA256Managed (CanReuseTransform == true)
- If using a custom hash, implement ICryptoTransform so CanReuseTransform returns true and state resets correctly
- Check hashAlgorithm.CanReuseTransform before calling Sign and swap algorithms if false
- Create a fresh algorithm instance per signing operation rather than reusing a consumed one
Example fix
// before HashAlgorithm alg = MyCustomHash.Create(); // CanReuseTransform == false manager.Sign(parts, alg); // after HashAlgorithm alg = new SHA256CryptoServiceProvider(); // reusable manager.Sign(parts, alg);
Defensive patterns
Strategy: validation
Validate before calling
if (!hashAlgorithm.CanReuseTransform)
throw new ArgumentException("Algorithm must support CanReuseTransform for package signing"); Type guard
bool IsReusableHash(HashAlgorithm a) => a?.CanReuseTransform == true;
Try / catch
try { manager.Sign(parts, hashAlgorithm); }
catch (ArgumentException ex) { /* fall back to SHA256CryptoServiceProvider */ hashAlgorithm = new SHA256CryptoServiceProvider(); } Prevention
- Prefer SHA256CryptoServiceProvider/SHA256Managed for package signing
- Assert CanReuseTransform in unit tests for any custom HashAlgorithm
- Create a new algorithm instance per signing operation
When it happens
Trigger: Calling signature generation (XmlSignatureManifest.GenerateManifest, reached via PackageDigitalSignatureManager.Sign) with a HashAlgorithm instance whose CanReuseTransform returns false (e.g. certain crypto provider-backed or non-streaming hash implementations).
Common situations: Passing a custom HashAlgorithm subclass that doesn't support transform reuse; using algorithm objects from a CSP that reset state after TransformBlock; migrating code that previously used the algorithm once elsewhere.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.UnsupportedHashAlgorithm
- ' ' ID is not a valid XSD ID.
- Cannot remove signature from read-only file.
- Object identifiers must be unique within the same signature.
- ReachPackaging_SigningDoesNotMeetPolicy
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ac42ddcefdbc79e1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlSignatureManifest.cs:482
/// <param name="hashAlgorithm">hash algorithm to hash with</param>
/// <param name="parts">parts to sign - possibly null</param>
/// <param name="relationshipSelectors">relationshipSelectors that represent the
/// relationships that have to be signed - possibly null</param>
/// <returns></returns>
internal static XmlNode GenerateManifest(
PackageDigitalSignatureManager manager,
XmlDocument xDoc,
HashAlgorithm hashAlgorithm,
IEnumerable<Uri> parts,
IEnumerable<PackageRelationshipSelector> relationshipSelectors)
{
Debug.Assert(manager != null);
Debug.Assert(xDoc != null);
Debug.Assert(hashAlgorithm != null);
// check args
if (!hashAlgorithm.CanReuseTransform)
throw new ArgumentException(SR.HashAlgorithmMustBeReusable);
// <Manifest>
XmlNode manifest = xDoc.CreateNode(XmlNodeType.Element,
XTable.Get(XTable.ID.ManifestTagName),
SignedXml.XmlDsigNamespaceUrl);
// add part references
if (parts != null)
{
// loop and write - may still be empty
foreach (Uri partUri in parts)
{
// generate a reference tag
manifest.AppendChild(GeneratePartSigningReference(manager, xDoc, hashAlgorithm, partUri));
}
}
// any relationship references?View on GitHub (pinned to 81131a70a4)