dotnet/wpf · error · ArgumentException
' ' ID is not a valid XSD ID.
Error message
'{0}' ID is not a valid XSD ID. What it means
VerifySignArguments validates the signatureId argument by calling XmlConvert.VerifyNCName, since an XSD ID must be a valid NCName; if the value fails, it throws ArgumentException (SR.NotAValidXmlIdString, formatted with the offending id) wrapping the original XmlException. The signature's Id XML attribute must be a legal XSD ID.
Solutions
- Use an NCName-safe id: start with a letter or underscore and use only letters, digits, '.', '-', '_' (e.g. '_sig1' or 'Signature1').
- Prefix numeric ids with an underscore: '_' + Guid.NewGuid().ToString("N").
- Pre-validate with XmlConvert.VerifyNCName(id) before calling Sign to fail early with your own message.
Example fix
// before
mgr.Sign(cert, parts, "123 my signature"); // ArgumentException: not a valid XSD ID
// after
string sigId = "_" + Guid.NewGuid().ToString("N"); // valid NCName
XmlConvert.VerifyNCName(sigId);
mgr.Sign(cert, parts, sigId); Defensive patterns
Strategy: validation
Validate before calling
try { XmlConvert.VerifyNCName(signatureId); }
catch (XmlException) { throw new InvalidOperationException($"'{signatureId}' is not a valid NCName/XSD ID."); } Type guard
bool IsValidXsdId(string s) => !string.IsNullOrEmpty(s) && (char.IsLetter(s[0]) || s[0] == '_') && s.All(c => char.IsLetterOrDigit(c) || c == '.' || c == '-' || c == '_' || c == ':');
Try / catch
try { mgr.Sign(cert, parts, sigId); }
catch (ArgumentException ex) when (ex.ParamName == "signatureId") { /* use an NCName-safe id */ } Prevention
- Start ids with a letter or underscore, never a digit.
- Only use letters, digits, '.', '-', '_' in ids; no spaces.
- Wrap GUIDs: '_' + guid.ToString("N").
When it happens
Trigger: Calling Sign() overload that takes an id (via signatureObjects/objectReferences or the id parameter) with a string that is not an NCName — e.g. contains spaces, starts with a digit, is empty, or contains ':' or other invalid characters.
Common situations: Passing a GUID-like string that starts with a digit, using a display name with spaces as the signature id, or localizing/serializing ids with invalid characters.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Object identifiers must be unique within the same signature.
- Specified object ID conflicts with predefined Package…
- Specified part to sign does not exist.
- Cannot remove signature from read-only file.
- Feature ID string cannot have zero length.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/57242a4a48178c27.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/PackageDigitalSignatureManager.cs:980
//if (ids.Contains(obj.Id))
if (ids.Exists(new StringMatchPredicate(obj.Id).Match))
throw new ArgumentException(SR.SignatureObjectIdMustBeUnique, nameof(signatureObjects));
else
ids.Add(obj.Id);
}
}
// ensure id is legal Xml id
if (!string.IsNullOrEmpty(signatureId))
{
try
{
// An XSD ID is an NCName that is unique.
System.Xml.XmlConvert.VerifyNCName(signatureId);
}
catch (System.Xml.XmlException xmlException)
{
throw new ArgumentException(SR.Format(SR.NotAValidXmlIdString, signatureId), nameof(signatureId), xmlException);
}
}
}
/// <summary>
/// Returns true if the given enumerator is null or empty
/// </summary>
/// <param name="enumerable">may be null</param>
/// <returns>true if enumerator is empty or null</returns>
private bool EnumeratorEmptyCheck(System.Collections.IEnumerable enumerable)
{
if (enumerable == null)
return true; // null means empty
// see if it's really a collection as this is more efficient than enumerating
if (enumerable is System.Collections.ICollection collection)
{
return (collection.Count == 0);View on GitHub (pinned to 81131a70a4)