TechnitiumSoftware/DnsServer · error · ArgumentException
Web Service TLS certificate file must contain a certificate
Error message
Web Service TLS certificate file must contain a certificate with private key.
What it means
ArgumentException thrown by LoadWebServiceTlsCertificate when none of the certificates in the loaded PKCS #12 collection has a private key. The loader scans the collection for a cert with HasPrivateKey; without one the server cannot present a TLS endpoint, so it aborts.
Source
Thrown at DnsServerCore/DnsWebService.cs:2710
default:
throw new ArgumentException("Web Service TLS certificate file must be PKCS #12 formatted with .pfx or .p12 extension: " + tlsCertificatePath);
}
X509Certificate2Collection certificateCollection = X509CertificateLoader.LoadPkcs12CollectionFromFile(tlsCertificatePath, tlsCertificatePassword, X509KeyStorageFlags.PersistKeySet);
X509Certificate2 serverCertificate = null;
foreach (X509Certificate2 certificate in certificateCollection)
{
if (certificate.HasPrivateKey)
{
serverCertificate = certificate;
break;
}
}
if (serverCertificate is null)
throw new ArgumentException("Web Service TLS certificate file must contain a certificate with private key.");
List<SslApplicationProtocol> applicationProtocols = new List<SslApplicationProtocol>();
if (_webServiceEnableHttp3)
applicationProtocols.Add(new SslApplicationProtocol("h3"));
if (IsHttp2Supported())
applicationProtocols.Add(new SslApplicationProtocol("h2"));
applicationProtocols.Add(new SslApplicationProtocol("http/1.1"));
_webServiceSslServerAuthenticationOptions = new SslServerAuthenticationOptions
{
ApplicationProtocols = applicationProtocols,
ServerCertificateContext = SslStreamCertificateContext.Create(serverCertificate, certificateCollection, false)
};
_webServiceCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;View on GitHub (pinned to d0484b6c1e)
Solutions
- Re-export the PFX including the private key (mark key as exportable) from the source store/CA.
- Verify with openssl: 'openssl pkcs12 -in cert.pfx -info -noout' should list a private key.
- Re-issue/renew the certificate with an exportable private key if the key is non-exportable.
Example fix
# re-export including the private key openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx # verify a private key is present openssl pkcs12 -in server.pfx -info -noout -passin pass:****
Defensive patterns
Strategy: validation
Validate before calling
using var coll = new X509Certificate2Collection();
coll.Import(webServiceTlsCertificatePath, password, X509KeyStorageFlags.DefaultKeySet);
bool hasPrivate = coll.Cast<X509Certificate2>().Any(c => c.HasPrivateKey);
if (!hasPrivate)
throw new ArgumentException("PFX must contain a certificate with a private key."); Type guard
static bool PfxHasPrivateKey(string path, string password)
{
var coll = new X509Certificate2Collection();
coll.Import(path, password, X509KeyStorageFlags.DefaultKeySet);
return coll.Cast<X509Certificate2>().Any(c => c.HasPrivateKey);
} Try / catch
null
Prevention
- When exporting PFX, tick 'include private key' and 'mark key as exportable'.
- Validate the PFX with openssl before deploying.
- Renew/re-export certificates with an exportable private key.
When it happens
Trigger: Supplying a .pfx/.p12 that contains only public certificates (e.g. a CA chain) and no end-entity certificate with its private key, or a bundle where the private key was not exported.
Common situations: Exported the PFX without checking 'include private key'; exported only the chain; password-protected bundle opened but key absent; cert renewed and only public part re-bundled.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Web server '{_name}' TLS certificate file must contain a cer
- Web Service TLS certificate file must be PKCS #12 formatted
- Web server '{_name}' TLS certificate file must be PKCS #12 f
- Web Service TLS certificate file does not exists: {tlsCertif
- Web service TLS certificate path cannot be null or empty.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/a41da2c21b96554c.
Report an issue: GitHub.