dotnet/wpf · error · FileFormatException

SR.MultipleSignatureOrigins

Error message

SR.MultipleSignatureOrigins

What it means

The manager permits exactly one recognizable Digital Signature Origin part per package. During construction, when a second relationship resolves to a part whose content type matches the signature origin content type and an origin was already found, it throws FileFormatException(SR.MultipleSignatureOrigins). Multiple origins make the signature set ambiguous, so the package is rejected.

Solutions

  1. Delete one of the signature origin parts and its relationship from the root .rels, keeping a single origin
  2. Re-sign the package after RemoveAllSignatures so exactly one origin is created
  3. Rebuild the package from the pre-merge state and re-apply signatures
  4. Reject the package at intake with a validation step that counts origin relationships

Example fix

// before: two origin relationships in _rels/.rels
// after: keep one
// <Relationship Type=".../digital-signature/origin" Target="metadata/sig-origin.xml" TargetMode="Internal"/>
using var pkg = Package.Open(path, FileMode.Open, FileAccess.ReadWrite);
var signer = new PackageDigitalSignatureManager(pkg);
signer.RemoveAllSignatures();
signer.Sign(new Uri("/metadata/sig-origin.xml", UriKind.Relative));
Defensive patterns

Strategy: validation

Validate before calling

int originCount = pkg.GetRelationshipsByType(
    "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin")
    .Count(r => r.TargetMode == TargetMode.Internal &&
                pkg.PartExists(PackUriHelper.ResolvePartUri("/", r.TargetUri)));
bool ambiguous = originCount > 1;

Try / catch

try { var signer = new PackageDigitalSignatureManager(pkg); }
catch (FileFormatException)
{ /* reject merged/multi-origin package */ }

Prevention

When it happens

Trigger: Constructing PackageDigitalSignatureManager on a package that has two or more root relationships of the signature-origin type resolving to parts with the origin content type (application/vnd.openxmlformats-package.digital-signature-origin).

Common situations: Merging two signed packages; a signing tool appended a second origin instead of reusing the existing one; manual .rels editing duplicating the origin relationship.

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/9a90d6d5b3a62219. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/PackageDigitalSignatureManager.cs:1291

                        // don't resolve if external
                        if (r.TargetMode != TargetMode.Internal)
                            throw new FileFormatException(SR.PackageSignatureCorruption);

                        // resolve target (may be relative)
                        Uri targetUri = PackUriHelper.ResolvePartUri(r.SourceUri, r.TargetUri);

                        // if part does not exist - we throw
                        if (!_container.PartExists(targetUri))
                            throw new FileFormatException(SR.SignatureOriginNotFound);

                        PackagePart p = _container.GetPart(targetUri);

                        // inspect content type - ignore things we don't understand
                        if (p.ValidatedContentType().AreTypeAndSubTypeEqual(_originPartContentType))
                        {
                            // throw if more than one relationship to an origin part that we recognize
                            if (_originPartExists)
                                throw new FileFormatException(SR.MultipleSignatureOrigins);

                            // overwrite default if some container is using some other name
                            _originPartName = targetUri;
                            _originPart = p;
                            _originPartExists = true;
                        }
                    }
                }
                finally
                {
                    _originSearchConducted = true;
                }
            }
            return _originPartExists;
        }

        //------------------------------------------------------
        //

View on GitHub (pinned to 81131a70a4)