Error message
The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
Also printed as
- System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
The flags after the colon come from X509ChainStatusFlags and can be combined (for example "UntrustedRoot, RevocationStatusUnknown"). Self-signed server certificates also report UntrustedRoot. On Linux, .NET uses OpenSSL and the distribution's CA store; on Windows and macOS, the system certificate stores.
.NET SslStream / HttpClient — AuthenticationException (X509ChainStatusFlags.UntrustedRoot)
What it means
.NET built the server's certificate chain up to a root, and that root is not trusted by the platform's store (or the chain ends in a self-signed certificate that is not trusted). The certificate itself may be fine; the machine just does not trust the authority behind it. HttpClient reports it as the inner exception of "The SSL connection could not be established".
Why it happens
A company or private CA
commonInternal APIs, SQL Server with a domain CA certificate, or services in a lab use roots the machine (often a Linux container) does not have.
A TLS-inspecting proxy
commonRe-signed connections chain to the proxy's root. Windows machines usually have it through group policy, Linux containers and WSL do not.
A self-signed server certificate
commonSelf-signed certificates (including those of development servers) end in themselves and are reported as UntrustedRoot.
The container image lacks the root
occasionalA root installed on the host or in Windows is not inside the Linux container where the .NET app runs.
How to fix it
- 1.
Linux: install the root into the system store
.NET on Linux reads the OpenSSL store, so update-ca-certificates (or the distribution's equivalent) is enough; in containers, do it in the Dockerfile.
bash # Linux (incl. containers): .NET uses the OpenSSL system store sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates - 2.
Windows and macOS: trust the root in the system store
Import the root into LocalMachine\Root on Windows or the System keychain on macOS; .NET uses those stores.
text # Windows (elevated PowerShell): trust the root machine-wide Import-Certificate -FilePath .\corp-root-ca.cer -CertStoreLocation Cert:\LocalMachine\Root # macOS sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain corp-root-ca.pem - 3.
Trust a private root for one client
SocketsHttpHandler.SslOptions.CertificateChainPolicy with CustomRootTrust keeps full validation but anchors it in your root. A custom policy enables online revocation checking by default, so set RevocationMode to match what your CA publishes (in our test, private certificates without CRL/OCSP failed with RevocationStatusUnknown until NoCheck was set).
csharp // Trust one private root for this client only; chain, dates and name are still verified. var root = X509CertificateLoader.LoadCertificateFromFile("corp-root-ca.pem"); var handler = new SocketsHttpHandler(); handler.SslOptions.CertificateChainPolicy = new X509ChainPolicy { TrustMode = X509ChainTrustMode.CustomRootTrust, // a custom policy defaults to online revocation checks; use NoCheck only if the CA publishes no CRL/OCSP RevocationMode = X509RevocationMode.NoCheck, }; handler.SslOptions.CertificateChainPolicy.CustomTrustStore.Add(root); using var client = new HttpClient(handler); - 4.
Development: trust the ASP.NET Core dev certificate
dotnet dev-certs https --trust installs and trusts the localhost development certificate on Windows and macOS (on Linux, trusting it depends on the distribution).
bash # ASP.NET Core development certificate on localhost dotnet dev-certs https --trust
Related errors
The SSL connection could not be established, see inner exception..NET HttpClientThe remote certificate is invalid because of errors in the certificate chain: P….NET SslStream / HttpClientThe remote certificate was rejected by the provided RemoteCertificateValidation….NET SslStream / HttpClientcurl: (60) SSL certificate problem: self-signed certificate in certificate chaincurl (OpenSSL backend)