何が起きたか
SQL Serverに接続しようとしています — リモートの開発マシン、Dockerコンテナ、または新しくプロビジョニングされた本番ホストかもしれません — しかし接続の代わりに次のエラーが表示されます:
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.)
TCPハンドシェイクは成功しています — サーバーには到達できています。しかしTLSが失敗しました。SQL ServerのSSL証明書がWindowsの信頼済みCAによって署名されていないためです。SQL Server 2022とODBC Driver 18がデフォルトでEncrypt=Trueを強制するようになってから、このエラーははるかに頻繁に発生するようになりました。ドライバーのアップグレード後にこの問題が発生した場合、まさにそれが原因です。
まず診断する
すぐに修正しようとしないでください。自分が実際にどのシナリオにいるかを確認してください:
- 自己署名証明書 — SQL Serverがインストール時に独自の証明書を生成したもの。開発環境やステージング環境では標準的です。
- 内部CA証明書 — WindowsのTrusted Rootストアに含まれていない企業CAによって発行された証明書。
- 期限切れまたはCN不一致 — 証明書は存在するが、ホスト名が一致しないか、先週の火曜日に期限切れになっている。
SQL Serverが実際に使用している証明書を確認します:
- SQL Server構成マネージャーを開く → SQL Serverネットワーク構成 → MSSQLSERVERのプロトコル → 右クリックしてプロパティ → 証明書タブ。
- サムプリントをメモします。次にPowerShellで証明書を確認します:
# LocalMachine\Myストア内の証明書を一覧表示(SQL Serverが参照する場所)
Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, Thumbprint, NotAfter, Issuer
サムプリントを構成マネージャーに表示されていたものと照合します。IssuerにCN=SQL Server Internal CAやマシン名だけが表示されている場合、それは自己署名証明書です。それが原因です。
解決策1 — クライアントで証明書を信頼する(開発環境では最速)
クライアントマシンを管理しており、開発環境または内部サーバーの場合は、SQL Serverの証明書をエクスポートしてWindowsのTrusted Rootストアに追加します。
手順1:サーバーから証明書をエクスポートする
# SQL Serverホスト上で実行(管理者としてPowerShell)
$thumb = "PASTE_THUMBPRINT_HERE"
$cert = Get-Item "Cert:\LocalMachine\My\$thumb"
Export-Certificate -Cert $cert -FilePath "C:\sqlserver.cer" -Type CERT
手順2:.cerをクライアントにコピーしてインポートする
# クライアントマシン上で実行(管理者としてPowerShell)
Import-Certificate -FilePath "C:\sqlserver.cer" -CertStoreLocation "Cert:\LocalMachine\Root"
GUIを好む場合は、.cerファイルをダブルクリック → 証明書のインストール → ローカルコンピューター → 証明書をすべて次のストアに配置する → 信頼されたルート証明機関を選択します。
確認
Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*SQLSERVERHOSTNAME*" }
接続を再試行してください。接続文字列の変更は不要です — そのまま動作するはずです。
解決策2 — 接続文字列にTrustServerCertificate=Trueを追加する(クイックバイパス)
ローカル開発環境や一時的な修正には、証明書の検証を完全にスキップするようドライバーに指示できます。本番環境にはリリースしないでください。
# .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;
知っておくべき点:ODBC Driver 18以降はデフォルトがEncrypt=yesです。Driver 17はデフォルトがEncrypt=noでした。この1行の違いが、他に何も変更していないのにドライバーのアップグレード後に突然このエラーが発生する理由です。
解決策3 — SQL Serverに適切な証明書をインストールする(本番環境向けの方法)
本番環境には正しい修正が必要です。公開CA(Let's Encryptで問題なく動作します。EVが必要な場合はDigiCert)または内部PKIからの証明書を使用してください。
SQL Serverホストに証明書をインストールする
# PFX証明書(秘密鍵付き)をLocalMachine\Myにインポート
$pfxPath = "C:\certs\sqlserver.pfx"
$pfxPassword = ConvertTo-SecureString -String "yourpassword" -Force -AsPlainText
Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation "Cert:\LocalMachine\My" -Password $pfxPassword
SQL Serverに証明書を割り当てる
- SQL Server構成マネージャーを開きます。
- SQL Serverネットワーク構成 → MSSQLSERVERのプロトコル → 右クリック → プロパティ → 証明書タブに移動します。
- ドロップダウンから新しい証明書を選択します。
- SQL Serverサービスを再起動します。
Restart-Service -Name MSSQLSERVER -Force
すでにCAを信頼しているクライアント — 企業PKIでADに参加しているマシン、または公開CAを使用しているすべてのクライアント — は、接続文字列を一切変更することなくクリーンに接続できます。
解決策4 — サーバーの暗号化を無効にする(完全に隔離された開発環境のみ)
暗号化が何も追加しない完全にエアギャップされた開発用SQL Serverを実行していますか?完全にオフにすることができます。
- SQL Server構成マネージャー → MSSQLSERVERのプロトコル → プロパティ → フラグタブ。
- 暗号化を強制するをいいえに設定します。
- SQL Serverを再起動します。
- 接続文字列に
Encrypt=Falseを追加します(またはODBC Driver 17を使用している場合は完全に削除します)。
隔離された開発環境のみ。実際のデータがあるサーバーでは絶対に使用しないでください。
修正が機能したことを確認する
# sqlcmdでのクイックテスト — TrustServerCertificateフラグなし
sqlcmd -S myserver -U sa -P yourpassword -Q "SELECT @@VERSION"
# または最小限の.NETスニペットでテスト
$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()
SQL Serverのバージョン文字列またはConnected: Openが表示されましたか?完了です。
覚えておくべきこと
- ODBC Driver 18がデフォルトを変更しました。 Driver 17は
Encrypt=noで出荷されましたが、Driver 18はEncrypt=yesに変更しました。Get-OdbcDriver -Name "*SQL*"でインストール済みバージョンを確認してください — コードを変更していないのに問題が発生した場合、おそらくこれが原因です。 - **TrustServerCertificateは本番環境ではコードの臭いです。**ローカルのノートパソコンでは問題ありません。リリース前に、コードベースとCI設定をgrepしてください — 本番の接続文字列に漏れ込む習性があります。
- **ドメイン参加マシンはグループポリシー経由でCA証明書を自動的に取得します。**組織内の一部のマシンは正常に接続できるが他のマシンは接続できない場合、失敗しているマシンが実際にドメインに参加しているかどうかを確認してください。GPO同期を逃したマシンのトラストストアには企業CAが存在しません。
- **コンテナ化されたSQL Serverは常に自己署名します。**DockerベースのSQL Serverインスタンスはすべて、初期状態でこのエラーが発生します。開発コンテナには接続文字列に
TrustServerCertificate=Trueを追加してください。本番コンテナには実際の証明書をマウントしてください。

