dotnet/wpf · error · InvalidOperationException

ReachPackaging_SigningDoesNotMeetPolicy

Error message

ReachPackaging_SigningDoesNotMeetPolicy

What it means

XpsDocument.SignDigitally throws InvalidOperationException when signing is requested but the document does not satisfy the signing policy. The IsSignable check rejects signing when the package contains parts or state that the XPS signing policy forbids (e.g. content that would make the signature invalid). It guards against creating a signature that is invalid under the OPC/XPS digital-signature policy.

Solutions

  1. Check the XpsDocument.IsSignable property before calling SignDigitally and abort or re-create the document if it returns false.
  2. Avoid modifying document content between opening/creating the XpsDocument and signing it.
  3. Re-open the package read-write from disk in its original, unmodified state and sign before making any edits.
  4. If the caller passed testIsSignable=false deliberately, verify the resulting signature afterwards; consider keeping testIsSignable=true.

Example fix

// before
xpsDoc.SignDigitally(cert, true, DigestAlgorithm.Sha1Uri);
// after
if (!xpsDoc.IsSignable)
    throw new InvalidOperationException("Document state does not permit signing; re-open without modifications.");
xpsDoc.SignDigitally(cert, true, DigestAlgorithm.Sha1Uri);
Defensive patterns

Strategy: validation

Validate before calling

if (!xpsDoc.IsSignable)
    throw new InvalidOperationException("Document cannot be signed as-is.");

Try / catch

try { xpsDoc.SignDigitally(cert, true, DigestAlgorithm.Sha256Uri); }
catch (InvalidOperationException ex) { /* document not signable: reopen unmodified and retry or fail */ }

Prevention

When it happens

Trigger: Calling XpsDocument.SignDigitally (with testIsSignable=true) on a document whose IsSignable property is false — typically after the document or its package parts were modified, or when the document structure disallows adding signatures.

Common situations: Re-signing an already-signed XPS after editing content; signing a document opened in a mode that disallows signing; automated XPS signing pipelines where prior writes invalidated signability.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/555175ffb9ce5300. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs:858

        private
        XpsDigitalSignature
        SignDigitally(
            X509Certificate                         certificate,
            bool                                    embedCertificate,
            XpsDigSigPartAlteringRestrictions       restrictions,
            String                                  signatureId,
            bool                                    testIsSignable
            )
        {
            ArgumentNullException.ThrowIfNull(certificate);

            if( CurrentXpsManager == null )
            {
                throw new InvalidOperationException(SR.ReachPackaging_DocumentWasClosed);
            }
            if( testIsSignable && !IsSignable )
            {
                throw new InvalidOperationException(SR.ReachPackaging_SigningDoesNotMeetPolicy);              
            }
            EnsureSignatures();
            //
            // List of RelationshipSelectors that need to be signed
            //
            List<PackageRelationshipSelector> selectorList =  
                new List<PackageRelationshipSelector>();

            //
            // This is being used as a Set class so the second Uri Value is irrelevent
            //
            Dictionary<Uri,Uri> dependentList = new Dictionary<Uri,Uri> ();
            CollectSelfAndDependents( dependentList, selectorList,  restrictions );

            PackageDigitalSignature packSignature =
                CurrentXpsManager.Sign(dependentList.Keys,
                                         certificate,
                                         embedCertificate,

View on GitHub (pinned to 81131a70a4)