microsoft/aspire · error · ArgumentException

The provided certificate must have a private key.

Error message

The provided certificate must have a private key.

What it means

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.

Solutions

  1. Load a combined PFX containing the private key: new X509Certificate2("cert.pfx", password).
  2. Combine cert and key PEMs before use: X509Certificate2.CreateFromPemFile(certPem, keyPem), optionally export to PFX for Windows compatibility.
  3. Re-export the certificate from the CA/store including the private key (pkcs12 format).
  4. Pre-validate with cert.HasPrivateKey before constructing the annotation and fail with a clear config error.

Example fix

// before
var cert = X509Certificate2.CreateFromPemFile("cert.pem", null); // no key -> throws later
var annotation = new HttpsCertificateAnnotation { Certificate = cert };
// after
var cert = X509Certificate2.CreateFromPemFile("cert.pem", "key.pem");
var annotation = new HttpsCertificateAnnotation { Certificate = cert };
Defensive patterns

Strategy: validation

Validate before calling

// before assigning
if (cert is not null && !cert.HasPrivateKey)
    throw new InvalidOperationException("Certificate must include a private key (use PFX or cert+key PEMs).");

Type guard

static bool HasPrivateKey(this X509Certificate2? cert) => cert is not null && cert.HasPrivateKey;

Try / catch

try
{
    var annotation = new HttpsCertificateAnnotation { Certificate = cert };
}
catch (ArgumentException ex) when (ex.Message.Contains("private key"))
{
    // reload the cert with its key (PFX or CreateFromPemFile(certPem, keyPem))
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/bacf99a1ad6f8fb8. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/ApplicationModel/HttpsCertificateAnnotation.cs:35

    private bool? _useDeveloperCertificate;

    /// <summary>
    /// Sets an <see cref="X509Certificate2"/> instance associated with this annotation.
    /// If a certificate is provided, it must have a private key; otherwise, an <see cref="ArgumentException"/> is thrown when setting the value.
    /// </summary>
    public X509Certificate2? Certificate
    {
        get => _certificate;
        init
        {
            if (value != null && _useDeveloperCertificate == true)
            {
                throw new ArgumentException("Cannot set both UseDeveloperCertificate and Certificate properties.", nameof(value));
            }

            if (value?.HasPrivateKey == false)
            {
                throw new ArgumentException("The provided certificate must have a private key.", nameof(value));
            }

            try
            {
                if (value != null && value.PublicKey == null)
                {
                    throw new ArgumentException("The provided certificate must have a valid public key.", nameof(value));
                }
            }
            catch (CryptographicException ex)
            {
                throw new ArgumentException("The provided certificate is invalid.", nameof(value), ex);
            }

            _certificate = value;
        }
    }

View on GitHub (pinned to 25830f84bd)