dotnet/wpf · error · CryptographicException
SR.DigSigCannotLocateCertificate
Error message
SR.DigSigCannotLocateCertificate
What it means
GetPrivateKeyForSigning looks up the signer certificate by thumbprint in the certificate store when the provided X509Certificate2 lacks an accessible private key. If no matching certificate with a private key is found, CryptographicException(SR.DigSigCannotLocateCertificate) is thrown.
Solutions
- Install the certificate with its private key (import the PFX into CurrentUser\My via certmgr or Import-PfxCertificate).
- Pass an X509Certificate2 instance that already has PrivateKey set so the store lookup is skipped.
- Verify the private key exists: check cert.HasPrivateKey before signing.
- If the key is on a smart card/HSM, ensure the CSP/KSP is installed and the token is accessible to the running user.
Example fix
// before: public-only cert
X509Certificate2 cert = new X509Certificate2("signer.cer");
dsm.Sign(toSign, cert); // throws
// after: load PFX with private key
X509Certificate2 cert = new X509Certificate2("signer.pfx", pfxPassword, X509KeyStorageFlags.MachineKeySet);
dsm.Sign(toSign, cert); Defensive patterns
Strategy: validation
Validate before calling
bool canSign = signer != null && signer.HasPrivateKey;
if (!canSign)
{
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
canSign = store.Certificates.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true)
.Count > 0;
} Type guard
static bool PrivateKeyResolvable(X509Certificate2 c) =>
c != null && (c.HasPrivateKey ||
(new X509Store(StoreName.My, StoreLocation.CurrentUser) is var s) && false); // prefer explicit store check in caller code Try / catch
try { dsm.Sign(toSign, cert); }
catch (CryptographicException ex) when (ex.Message.Contains("Locate"))
{ /* private key not installed — prompt user to import PFX */ } Prevention
- Always check cert.HasPrivateKey before signing.
- Import PFX (not .cer) files when a signing key is required.
- Ensure the running account can access the key's CSP/KSP.
- Keep smart-card tokens connected and drivers installed.
When it happens
Trigger: Calling PackageDigitalSignatureManager.Sign with a certificate loaded without its private key (e.g. from a .cer file or a PFX imported without the key), and no cert with that thumbprint plus a private key exists in the personal store.
Common situations: Deploying only the public certificate to servers; PFX password lost so the key was never imported; certificates on smart cards not reachable from the process account; app pool identities lacking access to the key (though that often surfaces as a different access error).
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- SR.CertificateKeyTypeNotSupported
- SR.DigSigDuplicateCertificate
- SR.UnsupportedHashAlgorithm
- " }} " element found. Expected fixed page element ( }} ).
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5b4606e885d84581.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs:1137
// look for appropriate certificates
X509Store store = new X509Store(StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
collection = collection.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true);
if (collection.Count > 0)
{
if (collection.Count > 1)
throw new CryptographicException(SR.DigSigDuplicateCertificate);
signer = collection[0];
}
else
throw new CryptographicException(SR.DigSigCannotLocateCertificate);
}
finally
{
store.Close();
}
// get the corresponding AsymmetricAlgorithm
return GetPrivateKey(signer);
}
/// <summary>
/// This method validated the Reference tags as per the restrictions imposed
/// by the OPC spec.
/// NOTE: The same method is called from Verify and Sign methods. At verify time we need to make sure
/// that there is exactly one Package-specific reference. At Sign time we need to make sure that
/// there are no package-specific references in the list of references passed to Sign APIs as a
/// input parameter, since we will be generating Package-specific object.View on GitHub (pinned to 81131a70a4)