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=Falseto 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 toEncrypt=yes. Check your installed version withGet-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=Trueto your connection string. For production containers, mount a real cert.

