dotnet/wpf · error · ArgumentException

Duplicates not allowed - signature part already exists.

Error message

Duplicates not allowed - signature part already exists.

What it means

Before writing a new signature, Sign generates a signature part name and throws ArgumentException (SR.DuplicateSignature) if a part with that URI already exists in the package, to avoid overwriting or duplicating an existing signature part.

Solutions

  1. Remove leftover signature parts (via DeletePart) from the failed attempt before re-signing
  2. Inspect and clean the package's /_rels/DigitalSignatures and signature origin parts after a failed sign
  3. Recreate the package from source if its signature parts are in a corrupted state
  4. Catch ArgumentException and offer the user a 'repair package then re-sign' path

Example fix

// before
mgr.Sign(parts, cert); // retry after earlier failure -> duplicate signature part
// after
var existing = mgr.Signatures.Select(s => s.SignaturePart.Uri).ToList();
foreach (var uri in existing)
    pkg.DeletePart(uri);
mgr.Sign(parts, cert);
Defensive patterns

Strategy: try-catch

Validate before calling

Uri next = /* generated name */;
if (package.PartExists(next))
    package.DeletePart(next); // clean leftover from failed attempt

Try / catch

try { manager.Sign(parts, cert); }
catch (ArgumentException ex) { log.Error("Duplicate signature part", ex); /* cleanup and retry */ }

Prevention

When it happens

Trigger: A previous Sign call failed midway and left a pre-created signature/origin part behind; the generated signature part name collides with an existing part; signing the same package twice with deterministic naming where cleanup never happened.

Common situations: Retrying a failed sign operation on the same package without removing leftover parts; a crashed process leaving half-written signature parts; manually renaming or copying signature parts in the package.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

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

                throw new InvalidOperationException(SR.CannotSignReadOnlyFile);

            VerifySignArguments(parts, certificate, relationshipSelectors, signatureId, signatureObjects, objectReferences);

            // substitute default id if none given
            if (string.IsNullOrEmpty(signatureId))
            {
                signatureId = "packageSignature";   // default
            }

            // Make sure the list reflects what's in the package.
            // Do this before adding the new signature part because we don't want it included until it
            // is fully formed (and delaying the add saves us having to remove it in case there is an 
            // error during the Sign call).
            EnsureSignatures();

            Uri newSignaturePartName = GenerateSignaturePartName();
            if (_container.PartExists(newSignaturePartName))
                throw new ArgumentException(SR.DuplicateSignature);

            // Pre-create origin part if it does not already exist.
            // Do this before signing to allow for signing the package relationship part (because a Relationship
            // is added from the Package to the Origin part by this call) and the Origin Relationship part in case this is
            // a Publishing signature and the caller wants the addition of more signatures to break this signature.
            PackageRelationship relationshipToNewSignature = OriginPart.CreateRelationship(newSignaturePartName, TargetMode.Internal,
                    _originToSignatureRelationshipType);
            _container.Flush();     // ensure the origin relationship part is persisted so that any signature will include this newest relationship

            VerifyPartsExist(parts);

            // sign the data and optionally embed the certificate
            bool embedCertificateInSignaturePart = (_certificateEmbeddingOption == CertificateEmbeddingOption.InSignaturePart);

            // convert cert to version2 - more functionality
            if (certificate is not X509Certificate2 exSigner)
                exSigner = new X509Certificate2(certificate.Handle);

View on GitHub (pinned to 81131a70a4)