{"record":{"id":"55b7b91a1d5226da","repo":"TechnitiumSoftware/DnsServer","slug":"web-server-name-tls-certificate-file-must-con","errorCode":null,"errorMessage":"Web server '{_name}' TLS certificate file must contain a certificate with private key.","messagePattern":"Web server '(.+?)' TLS certificate file must contain a certificate with private key\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Apps/BlockPageApp/App.cs","lineNumber":494,"sourceCode":"\n                    default:\n                        throw new ArgumentException(\"Web server '\" + _name + \"' TLS certificate file must be PKCS #12 formatted with .pfx or .p12 extension: \" + webServerTlsCertificateFilePath);\n                }\n\n                X509Certificate2Collection webServerTlsCertificateCollection = X509CertificateLoader.LoadPkcs12CollectionFromFile(webServerTlsCertificateFilePath, webServerTlsCertificatePassword, X509KeyStorageFlags.PersistKeySet);\n                X509Certificate2? serverCertificate = null;\n\n                foreach (X509Certificate2 certificate in webServerTlsCertificateCollection)\n                {\n                    if (certificate.HasPrivateKey)\n                    {\n                        serverCertificate = certificate;\n                        break;\n                    }\n                }\n\n                if (serverCertificate is null)\n                    throw new ArgumentException(\"Web server '\" + _name + \"' TLS certificate file must contain a certificate with private key.\");\n\n                _sslServerAuthenticationOptions = new SslServerAuthenticationOptions()\n                {\n                    ServerCertificateContext = SslStreamCertificateContext.Create(serverCertificate, webServerTlsCertificateCollection, false)\n                };\n\n                _webServerTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;\n\n                _dnsServer.WriteLog(\"Web server '\" + _name + \"' TLS certificate was loaded: \" + webServerTlsCertificateFilePath);\n            }\n\n            private void StartTlsCertificateUpdateTimer()\n            {\n                if (_tlsCertificateUpdateTimer is null)\n                {\n                    _tlsCertificateUpdateTimer = new Timer(delegate (object? state)\n                    {\n                        if (!string.IsNullOrEmpty(_webServerTlsCertificateFilePath))","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/Apps/BlockPageApp/App.cs#L476-L512","documentation":"Thrown by BlockPageApp LoadWebServiceTlsCertificate after successfully loading the PKCS #12 bundle if none of the certificates in it contains a private key. A TLS server needs a certificate with its private key, so an empty/private-key-less bundle raises ArgumentException.","triggerScenarios":"Loading a .pfx/.p12 that was exported without the private key (e.g. only the public cert chain), so the loop finds no certificate with HasPrivateKey and serverCertificate stays null.","commonSituations":"Exporting a PFX from a CA/Windows cert store without marking 'export private key'; using a distribution public cert bundle; wrong password silently yielding a key-less result.","solutions":["Re-export the certificate ensuring the private key is included (Windows: 'Yes, export the private key'; OpenSSL: pass -inkey).","Confirm the 'webServerTlsCertificatePassword' matches the bundle so the private key loads.","Validate the PFX contains a key pair before deploying (e.g. 'openssl pkcs12 -info -in file.pfx')."],"exampleFix":"# re-export WITH private key\nopenssl pkcs12 -export -out blockpage.pfx -inkey privkey.pem -in fullchain.pem\n# verify a key is present\nopenssl pkcs12 -info -in blockpage.pfx -nokeys || echo \"NO PRIVATE KEY\"","handlingStrategy":"validation","validationCode":"var coll = X509CertificateLoader.LoadPkcs12CollectionFromFile(path, password, X509KeyStorageFlags.PersistKeySet);\nif (!coll.Any(c => c.HasPrivateKey))\n    throw new FormatException($\"PKCS #12 bundle '{path}' contains no certificate with a private key. Re-export including the private key.\");","typeGuard":"static bool PfxHasPrivateKey(string path, string? password)\n{\n    var coll = X509CertificateLoader.LoadPkcs12CollectionFromFile(path, password, X509KeyStorageFlags.PersistKeySet);\n    return coll.Any(c => c.HasPrivateKey);\n}","tryCatchPattern":null,"preventionTips":["When exporting a PFX, always include the private key.","Verify with 'openssl pkcs12 -info -in file.pfx' that a key is present.","Ensure the configured password matches the bundle."],"tags":["csharp","tls","certificate","private-key","pkcs12","technitium","block-page-app"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}