Fix SSL Error 'The certificate chain was issued by an authority that is not trusted' on SQL Server (Windows)

intermediate๐ŸชŸ Windows2026-05-12| Windows 10/11, SQL Server 2016โ€“2022, .NET / SSMS / pyodbc / JDBC clients

Error Message

A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)
#sqlserver#ssl#certificate#windows#trusted-root

What happened

You're connecting to SQL Server โ€” maybe a remote dev box, a Docker container, or a freshly provisioned production host โ€” and instead of a connection, you get this:

A connection was successfully established with the server, but then an error occurred during the login process.
(provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)

The TCP handshake succeeded โ€” the server is reachable. But TLS fell over because SQL Server's SSL certificate was signed by a CA that Windows doesn't trust. This became much more common after SQL Server 2022 and ODBC Driver 18 started enforcing Encrypt=True by default. If this broke after a driver upgrade, that's exactly why.

Diagnose first

Don't reach for a fix yet. Figure out which scenario you're actually in:

  • Self-signed cert โ€” SQL Server generated its own certificate at install time. Standard in dev and staging environments.
  • Internal CA cert โ€” Issued by a corporate CA that isn't in Windows' Trusted Root store.
  • Expired or mismatched CN โ€” The cert exists but either the hostname doesn't match or it expired last Tuesday.

Check which cert SQL Server is actually using:

  • Open SQL Server Configuration Manager โ†’ SQL Server Network Configuration โ†’ Protocols for MSSQLSERVER โ†’ right-click Properties โ†’ Certificate tab.
  • Note the thumbprint. Then verify the cert in PowerShell:
# List certs in the LocalMachine\My store (where SQL Server looks)
Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, Thumbprint, NotAfter, Issuer

Match the thumbprint to what Configuration Manager showed. If Issuer says something like CN=SQL Server Internal CA or just the machine name, it's self-signed. That's your culprit.

Solution 1 โ€” Trust the certificate on the client (quickest for dev)

You control the client machines and this is a dev or internal server? Export the SQL Server cert and drop it into the Windows Trusted Root store.

Step 1: Export the cert from the server

# Run on the SQL Server host (PowerShell as admin)
$thumb = "PASTE_THUMBPRINT_HERE"
$cert = Get-Item "Cert:\LocalMachine\My\$thumb"
Export-Certificate -Cert $cert -FilePath "C:\sqlserver.cer" -Type CERT

Step 2: Copy the .cer to the client, then import it

# Run on the CLIENT machine (PowerShell as admin)
Import-Certificate -FilePath "C:\sqlserver.cer" -CertStoreLocation "Cert:\LocalMachine\Root"

Prefer the GUI? Double-click the .cer file โ†’ Install Certificate โ†’ Local Machine โ†’ Place all certificates in the following store โ†’ Trusted Root Certification Authorities.

Verify

Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*SQLSERVERHOSTNAME*" }

Retry your connection. No connection string changes needed โ€” it should just work.

Solution 2 โ€” Add TrustServerCertificate=True to the connection string (quick bypass)

For local dev or a one-off fix, you can tell the driver to skip cert validation entirely. Don't ship this to production.

# .NET / ADO.NET
Server=myserver;Database=mydb;User Id=sa;Password=xxx;Encrypt=True;TrustServerCertificate=True;

# Python pyodbc
connection_string = (
    "DRIVER={ODBC Driver 18 for SQL Server};"
    "SERVER=myserver;"
    "DATABASE=mydb;"
    "UID=sa;PWD=xxx;"
    "Encrypt=yes;"
    "TrustServerCertificate=yes;"
)

# JDBC (Java)
jdbc:sqlserver://myserver:1433;databaseName=mydb;encrypt=true;trustServerCertificate=true;

Worth knowing: ODBC Driver 18+ defaults to Encrypt=yes. Driver 17 defaulted to Encrypt=no. That one-line difference is why this error appears out of nowhere after a driver upgrade with no other changes.

Solution 3 โ€” Install a proper certificate on SQL Server (the production path)

Production environments need a real fix. Use a cert from a public CA (Let's Encrypt works fine, DigiCert if you need EV) or your internal PKI.

Install the cert on the SQL Server host

# Import a PFX cert (with private key) into LocalMachine\My
$pfxPath = "C:\certs\sqlserver.pfx"
$pfxPassword = ConvertTo-SecureString -String "yourpassword" -Force -AsPlainText
Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation "Cert:\LocalMachine\My" -Password $pfxPassword

Assign the cert to SQL Server

  • Open SQL Server Configuration Manager.
  • Go to SQL Server Network Configuration โ†’ Protocols for MSSQLSERVER โ†’ right-click โ†’ Properties โ†’ Certificate tab.
  • Pick your new cert from the dropdown.
  • Restart the SQL Server service.
Restart-Service -Name MSSQLSERVER -Force

Any client that already trusts the CA โ€” machines enrolled in AD with corporate PKI, or anyone using a public CA โ€” connects cleanly with zero connection string changes.

Solution 4 โ€” Disable encryption on the server (isolated dev only)

Running a fully air-gapped dev SQL Server where encryption adds nothing? You can turn it off entirely.

  • In SQL Server Configuration Manager โ†’ Protocols for MSSQLSERVER โ†’ Properties โ†’ Flags tab.
  • Set Force Encryption to No.
  • Restart SQL Server.
  • Add Encrypt=False to your connection string (or drop it entirely if using ODBC Driver 17).

Isolated dev only. Never on a server with real data.

Confirm the fix worked

# Quick test with sqlcmd โ€” no TrustServerCertificate flag
sqlcmd -S myserver -U sa -P yourpassword -Q "SELECT @@VERSION"

# Or test with a minimal .NET snippet
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Server=myserver;Database=master;User Id=sa;Password=xxx;Encrypt=True;"
$conn.Open()
Write-Host "Connected: $($conn.State)"
$conn.Close()

See the SQL Server version string or Connected: Open? You're done.

Things worth remembering

  • ODBC Driver 18 changed the default. Driver 17 shipped with Encrypt=no; Driver 18 flipped it to Encrypt=yes. Check your installed version with Get-OdbcDriver -Name "*SQL*" โ€” it's probably the culprit if this broke without any code changes.
  • TrustServerCertificate is a code smell in production. Fine for a local laptop. Before shipping, grep your codebase and CI configs โ€” it has a habit of leaking into prod connection strings.
  • Domain-joined machines get CA certs automatically via Group Policy. If some machines in your org connect fine but others don't, check whether the failing ones are actually domain-joined. A machine that missed GPO sync won't have the corporate CA in its trust store.
  • Containerized SQL Server always self-signs. Every Docker-based SQL Server instance hits this error out of the box. For dev containers, add TrustServerCertificate=True to your connection string. For production containers, mount a real cert.

Related Error Notes