dotnet / dotnet/yarp

[YARP Ingress Controller] TLS handshake missing private key: `The server mode SSL must use a certificate with the associated private key`

Open
#3,051 1 comment 0 reactions 0 assignees View on GitHub
Type: Bug
Dominant language
C#
Stars
9.6k
Forks
933
Avg merge
12d 18h
Merged PRs (30d)
2

Description

### Describe the bug
Hi there,

I implemented a HTTPS termination for YARP Ingress Controller this week. During my test, I found that TLS handshake would fail and error was `The server mode SSL must use a certificate with the associated private key`.

I checked the documentation. In summary, a C# `X509Certificate2` instance by default has an ephemeral private key in memory linked by a memory pointer. ASP.NET Kestrel relies on OpenSSL on Linux for TLS handshake. However, the OpenSSL under the hood of Linux doesn't know how to get its private key by pointer so OpenSSL thinks the private key is missing.

> I would like to make a PR fix for you to review and get your feedback if you regard it as a real bug.

#### My fix

> We need to export the private key so that the PFX file itself includes the private key. The code has done it for Windows.

The following code would eliminate the TLS handshake error and my HTTPS termination would work:
```csharp
if (OperatingSystem.IsLinux())
{
var pfx = certificate.Export(X509ContentType.Pkcs12);
certificate = X509CertificateLoader.LoadPkcs12(pfx, null); // a class in .NET9
}
```

I would say the current code would also work with slight modification based on .NET 8, even if I haven't tested:

```csharp
if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux())
{
// Cert needs converting. Read https://github.com/dotnet/runtime/issues/23749#issuecomment-388231655
using var convertedCertificate = X509Certificate2.CreateFromPem(certString, privateString);
return new X509Certificate2(convertedCertificate.Export(X509ContentType.Pkcs12));
}
```

### To Reproduce

#### Reproduce

Use a certificate type secret in Kubernetes and use the generated certificate for TLS handshake by [public X509Certificate2 ConvertCertificate(NamespacedName namespacedName, V1Secret secret)](https://github.com/dotnet/yarp/blob/main/src/Kubernetes.Controller/Certificates/CertificateHelper.cs#L26).

#### Exceptions

```
[2026-09-03 16:05:36 DBG] [Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware] Failed to authenticate HTTPS connection.
System.Security.Authentication.AuthenticationException: The server mode SSL must use a certificate with the associated private key.
at System.Net.Security.SslStream.AcquireServerCredentials(Byte[]& thumbPrint)
at System.Net.Security.SslStream.GenerateToken(ReadOnlySpan`1 inputBuffer, Int32& consumed)
at System.Net.Security.SslStream.NextMessage(ReadOnlySpan`1 incomingBuffer, Int32& consumed)
at System.Net.Security.SslStream.ProcessTlsFrame(Int32 frameSize)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware.OnConnectionAsync(ConnectionContext context)
```
### Further technical details

#### Packages

```

```
#### Platform
Docker image `mcr.microsoft.com/dotnet/sdk:10.0-noble` on Ubuntu host machine

Contributor guide

Open the contributing guide

Research direction

Start with ConvertCertificate in src/Kubernetes.Controller/Certificates/CertificateHelper.cs, then reproduce the certificate-secret flow in the Ubuntu-based Docker environment described in the issue. Verify the resulting certificate retains its private key and that the YARP HTTPS termination completes the TLS handshake without the reported authentication exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, docker, kubernetes, ubuntu
Domain
backend, networking, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.