dotnet/wpf · error · ArgumentException
SR.PackageSpecificReferenceTagMustBeUnique
Error message
SR.PackageSpecificReferenceTagMustBeUnique
What it means
ValidateReferences walks the signature's <Reference> elements. Per the OPC spec there must be exactly one package-specific reference (URI equal to the OpcLinkAttrValue) pointing at the package <Object>. If such a reference is encountered where package-specific references are not allowed, ArgumentException(SR.PackageSpecificReferenceTagMustBeUnique) is thrown.
Solutions
- Re-sign the package with PackageDigitalSignatureManager.Sign so references are structured per the OPC profile.
- Remove the package-specific <Reference> from the part-level reference set; it must exist only in the allowed group.
- Inspect the signature's SignedXml Reference URIs and fix the one using the OpcLink value.
- Reject/strip non-conformant third-party signatures before verification.
Example fix
// before: package-specific reference among part refs <Reference URI="#idPackageObject">...</Reference> <!-- inside part manifest refs --> // after: re-sign correctly var dsm = new PackageDigitalSignatureManager(pkg); dsm.Sign(toSign, cert); // places the package Object reference per OPC spec
Defensive patterns
Strategy: validation
Validate before calling
// Scan part-level references for the package-specific URI before Verify
var opcUri = "#idPackageObject"; // XTable.OpcLinkAttrValue
var badRefs = doc.SelectNodes("//*[local-name()='Reference']/@URI")
.Cast<XmlAttribute>()
.Where(a => a.Value == opcUri);
// only the allowed group may contain it; >0 elsewhere is invalid Type guard
static bool NoOpcLinkInPartRefs(IEnumerable<string> partRefUris, string opcUri) =>
!partRefUris.Contains(opcUri); Try / catch
try { dsm.VerifySignatures(true); }
catch (ArgumentException ex) { /* misplaced package-specific reference — reject/re-sign */ } Prevention
- Never add a package Object reference into part-level reference lists.
- Use PackageDigitalSignatureManager.Sign to build references correctly.
- Validate third-party signatures' Reference URIs before verification.
- Strip and re-sign non-conformant signatures.
When it happens
Trigger: Verifying a signature or adding custom object tags when a <Reference> with the package-specific URI appears in a reference set that forbids it — e.g. a part-level reference list contains a reference to the package Object instead of a real part URI.
Common situations: Custom signing code that adds a package-specific reference into the wrong reference group; signatures crafted by third-party tools that mix part references and package Object references; verifying signatures not produced by the OPC-aware .NET signer.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- SR.MultipleRelationshipTransformsFound
- SR.PackageSignatureObjectTagRequired
- SR.RequiredXmlAttributeMissing (uri)
- SR.SignatureObjectIdMustBeUnique
- SR.RelationshipTransformNotFollowedByCanonicalizationTransfo…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/62d6922b86fbb34a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs:1179
private void ValidateReferences(IEnumerable references, bool allowPackageSpecificReferences)
{
Debug.Assert(references != null);
bool packageReferenceFound = false;
TransformChain currentTransformChain;
foreach (Reference currentReference in references)
{
//As per the OPC spec, Uri attribute in Reference elements MUST refer using fragment identifiers
//This implies that Uri cannot be absolute.
if (currentReference.Uri.StartsWith("#", StringComparison.Ordinal))
{
//As per the OPC spec, there MUST be exactly one package specific reference to the
//package specific <Object> element
if (string.Equals(currentReference.Uri, XTable.Get(XTable.ID.OpcLinkAttrValue), StringComparison.Ordinal))
{
if (!allowPackageSpecificReferences)
throw new ArgumentException(SR.PackageSpecificReferenceTagMustBeUnique);
//If there are more than one package specific tags
if (packageReferenceFound)
throw new XmlException(SR.MoreThanOnePackageSpecificReference);
else
packageReferenceFound = true;
}
currentTransformChain = currentReference.TransformChain;
for(int j=0; j<currentTransformChain.Count; j++)
{
//As per the OPC spec, only two transforms are supported for the reference tags
if (!IsValidXmlCanonicalizationTransform(currentTransformChain[j].Algorithm))
throw new XmlException(SR.UnsupportedTransformAlgorithm);
}
}
elseView on GitHub (pinned to 81131a70a4)