dotnet/wpf · error · XmlException

SR.XmlSignatureParseError

Error message

SR.XmlSignatureParseError

What it means

ParsePackageDataObject parses the OPC-specific <Object> element of an XML digital signature. The WPF packaging code requires that the package <Object> tag contain exactly two children: a <Manifest> and <SignatureProperties>. If the child node count is anything other than 2, the signature XML is considered structurally invalid and an XmlException(SR.XmlSignatureParseError) is thrown.

Solutions

  1. Re-sign the package with PackageDigitalSignatureManager.Sign so a conformant package Object element is generated.
  2. Compare the <Object> element of the failing signature against one produced by Sign; remove or merge extra children so exactly <Manifest> and <SignatureProperties> remain.
  3. If signatures come from a third-party signer, ensure it follows the OPC digital-signature profile (Object with exactly two children).
  4. Load the package from a known-good copy or from source control instead of the corrupted one.

Example fix

// before: signature Object rewritten by an external tool
<Object Id="idPackageObject">...
  <extra:Property/> <!-- third child → throws -->
</Object>
// after: re-sign in C#
using (Package pkg = Package.Open(path, FileMode.Open, FileAccess.ReadWrite))
{
    var dsm = new PackageDigitalSignatureManager(pkg);
    dsm.Sign(toSign, cert);
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the signature XML's package Object child count
var doc = new XmlDocument(); doc.Load(signaturePartStream);
var obj = doc.GetElementById("idPackageObject") ??
          doc.SelectSingleNode("//*[local-name()='Object' and @Id='idPackageObject']");
bool valid = obj != null &&
             obj.ChildNodes.Cast<XmlNode>().Count(n => n.NodeType == XmlNodeType.Element) == 2;

Type guard

static bool HasExactlyTwoElementChildren(XmlElement obj) =>
    obj != null && obj.ChildNodes.Cast<XmlNode>().Count(n => n.NodeType == XmlNodeType.Element) == 2;

Try / catch

try { var manifest = signature.PartManifest; }
catch (XmlException ex) { /* log malformed signature; treat package as untrusted */ }

Prevention

When it happens

Trigger: Calling PackageDigitalSignatureManager.Verify, VerifySignatures, or any accessor (SigningTime, TimeFormat, PartManifest, RelationshipManifest) on a PackageSignature whose embedded <Object> element has children other than exactly one <Manifest> plus one <SignatureProperties> — e.g. comments processed as nodes, extra elements, or a missing child.

Common situations: Hand-editing or post-processing the signature XML with a tool that rewrites/normalizes the Object element; signatures produced by non-.NET OPC signers that emit extra property elements inside the package Object; XML documents mangled by template or encoding round-trips.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs:979

        /// <summary>
        /// Full parse of the Package-specific Object tag
        /// </summary>
        /// <remarks>Side effect of updating _signingTime, _signingTimeFormat, 
        /// _partManifest, _partEntryManifest and _relationshipManifest</remarks>
        /// <exception cref="XmlException">throws if markup does not match OPC spec</exception>
        private void ParsePackageDataObject()
        {
            if (!_dataObjectParsed)
            {
                EnsureXmlSignatureParsed();

                // find the package-specific Object tag
                XmlNodeList nodeList = GetPackageDataObject().Data;

                // The legal parent is a "Package" Object tag with 2 children
                // <Manifest> and <SignatureProperties>
                if (nodeList.Count != 2)
                    throw new XmlException(SR.XmlSignatureParseError);

                // get a NodeReader that allows us to easily and correctly skip comments
                XmlReader reader = new XmlNodeReader(nodeList[0].ParentNode);

                // parse the <Object> tag - ensure that it is in the correct namespace
                reader.Read();  // enter the Object tag
                if (!string.Equals(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl, StringComparison.Ordinal))
                    throw new XmlException(SR.XmlSignatureParseError);

                string signaturePropertiesTagName = XTable.Get(XTable.ID.SignaturePropertiesTagName);
                string manifestTagName = XTable.Get(XTable.ID.ManifestTagName);
                bool signaturePropertiesTagFound = false;
                bool manifestTagFound = false;
                while (reader.Read() && (reader.NodeType == XmlNodeType.Element))
                {
                    if (reader.MoveToContent() == XmlNodeType.Element
                        && (string.Equals(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl, StringComparison.Ordinal))
                        && reader.Depth == 1)

View on GitHub (pinned to 81131a70a4)