{"record":{"id":"bacf99a1ad6f8fb8","repo":"microsoft/aspire","slug":"the-provided-certificate-must-have-a-private-key","errorCode":null,"errorMessage":"The provided certificate must have a private key.","messagePattern":"The provided certificate must have a private key\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/HttpsCertificateAnnotation.cs","lineNumber":35,"sourceCode":"    private bool? _useDeveloperCertificate;\n\n    /// <summary>\n    /// Sets an <see cref=\"X509Certificate2\"/> instance associated with this annotation.\n    /// If a certificate is provided, it must have a private key; otherwise, an <see cref=\"ArgumentException\"/> is thrown when setting the value.\n    /// </summary>\n    public X509Certificate2? Certificate\n    {\n        get => _certificate;\n        init\n        {\n            if (value != null && _useDeveloperCertificate == true)\n            {\n                throw new ArgumentException(\"Cannot set both UseDeveloperCertificate and Certificate properties.\", nameof(value));\n            }\n\n            if (value?.HasPrivateKey == false)\n            {\n                throw new ArgumentException(\"The provided certificate must have a private key.\", nameof(value));\n            }\n\n            try\n            {\n                if (value != null && value.PublicKey == null)\n                {\n                    throw new ArgumentException(\"The provided certificate must have a valid public key.\", nameof(value));\n                }\n            }\n            catch (CryptographicException ex)\n            {\n                throw new ArgumentException(\"The provided certificate is invalid.\", nameof(value), ex);\n            }\n\n            _certificate = value;\n        }\n    }\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/HttpsCertificateAnnotation.cs#L17-L53","documentation":"HttpsCertificateAnnotation.Certificate requires a certificate with an associated private key, because the annotation is used to configure HTTPS endpoints that must terminate TLS. Assigning an X509Certificate2 whose HasPrivateKey is false throws ArgumentException.","triggerScenarios":"Loading only the public portion of a certificate (e.g. X509Certificate2.CreateFromPemFile with a cert-only PEM, or reading a .cer/.crt file) and assigning it to the Certificate property.","commonSituations":"Certificate exported without the private key; PFX imported with Exportable/load flags that drop the key; separate cert/key PEM files where only the cert file was passed.","solutions":["Load a combined PFX containing the private key: new X509Certificate2(\"cert.pfx\", password).","Combine cert and key PEMs before use: X509Certificate2.CreateFromPemFile(certPem, keyPem), optionally export to PFX for Windows compatibility.","Re-export the certificate from the CA/store including the private key (pkcs12 format).","Pre-validate with cert.HasPrivateKey before constructing the annotation and fail with a clear config error."],"exampleFix":"// before\nvar cert = X509Certificate2.CreateFromPemFile(\"cert.pem\", null); // no key -> throws later\nvar annotation = new HttpsCertificateAnnotation { Certificate = cert };\n// after\nvar cert = X509Certificate2.CreateFromPemFile(\"cert.pem\", \"key.pem\");\nvar annotation = new HttpsCertificateAnnotation { Certificate = cert };","handlingStrategy":"validation","validationCode":"// before assigning\nif (cert is not null && !cert.HasPrivateKey)\n    throw new InvalidOperationException(\"Certificate must include a private key (use PFX or cert+key PEMs).\");","typeGuard":"static bool HasPrivateKey(this X509Certificate2? cert) => cert is not null && cert.HasPrivateKey;","tryCatchPattern":"try\n{\n    var annotation = new HttpsCertificateAnnotation { Certificate = cert };\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"private key\"))\n{\n    // reload the cert with its key (PFX or CreateFromPemFile(certPem, keyPem))\n}","preventionTips":["Always load PFX (PKCS#12) files that contain the private key.","Use X509Certificate2.CreateFromPemFile(certPem, keyPem) with both files.","Check cert.HasPrivateKey immediately after loading.","Verify secret mounts actually contain the key file, not just the certificate."],"tags":["dotnet","aspire","https","certificate","x509"],"backgroundTag":"invalid-argument-value","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}