Windowsで問題なく動いていたBlazor WebアプリをMacBook Pro(Apple Silicon / M4)へ移行した直後に、Azure SQL Databaseへだけ接続できなくなるケースがあります。本記事では「ツールでは繋がるのにアプリだけ失敗する」状況を前提に、原因の切り分けと設定確認の勘所、そしてSerilog設定ミスが“接続エラー”に見えた実例まで、再発防止の形で整理します。
発生した症状:Azure Data StudioはOK、でもBlazorアプリはError 26
今回の状況は、切り分けの材料が揃っているのがポイントです。まず「何が成功して、何が失敗しているか」を表に落とすと、疑うべき場所が見えてきます。
| 確認項目 | 結果 | 読み取れること |
|---|---|---|
| Azure Data Studio から Azure SQL Database へ接続 | 成功 | サーバー名/DNS、認証情報、Azure側のファイアウォール(送信元IP)などは概ねOKの可能性が高い |
Macから nc -v xxxx.database.windows.net 1433 | 成功 | TCP 1433 の到達性はある(ネットワーク経路・ポートブロックの可能性が低い) |
| BlazorアプリからDB接続 | 失敗 | アプリの設定(接続文字列、環境別設定、上書き要因、起動時コンポーネント)が本命になりやすい |
アプリ側では以下のエラーが出ていました。
A network-related or instance-specific error occurred while establishing a connection to SQL Server.
(provider: TCP Provider, error: 26 – Error Locating Server/Instance Specified)
Error 26(TCP Provider)の意味と、今回それが示すこと
TCP Provider の Error 26 は、クライアントが「指定したSQL Server(または互換エンドポイント)に到達できない/見つけられない」時に出る代表的なエラーです。原因の候補は広く、典型パターンは次の通りです。
- サーバー名・ホスト名・ポート指定の誤り(
tcp:、,1433、余計な文字の混入など) - ファイアウォール、VPN、プロキシ、セキュリティソフトによるブロック
- Azure SQL側のネットワーク構成(パブリック/プライベート)と接続元の不一致
- 接続文字列は正しいが、アプリが参照している値が別物(設定ファイルの読み込み順、環境変数、ユーザーシークレットの上書き)
- 起動時に動く別機能(ログ/ヘルスチェック/初期化処理)が先にDBへ接続し、そこで落ちている
ただし今回のように「Azure Data Studioで接続できる」「ncで1433に到達できる」が揃うと、ネットワークやAzure SQL自体が主犯である可能性は下がります。ここから導ける結論はシンプルで、優先順位はこうなります。
ツールで繋がるなら、まず疑うべきは“Blazorアプリが実際に使っている設定”
最初に確認したい前提:BlazorはどこでDB接続しているか
念のため押さえておきたいのが、Blazorの実行形態による違いです。
| Blazorの形態 | DB接続が行われる場所 | 注意点 |
|---|---|---|
| Blazor Server | サーバー側(ASP.NET Core) | サーバーがDBに繋ぐので、接続文字列や環境設定がそのまま効く |
| Blazor WebAssembly(WASM) | ブラウザ側(クライアント) | 原則としてDBへ直接接続しない(API経由が基本)。「クライアントからDBへ」は構成として危険&成立しにくい |
| Hosted(WASM + Server) | DB接続はServer側 | 起動プロジェクトや環境変数の掛かり方で、参照している設定が変わりやすい |
WindowsではServerプロジェクトを起動していたのに、Mac移行後に起動プロファイルやスタートアッププロジェクトが変わって「違う側を動かしていた」という事故も起きます。まずは“どのプロジェクト(どのプロファイル)で動かしているか”を再確認すると、最短でズレが見つかることがあります。
結論に直結する観点:「接続文字列が正しい」より「実効値が一致しているか」
質問ではAzureポータルのODBC/ADO.NET接続文字列をコピーして試しています。提示の形式自体は一般的で、接続文字列そのものが致命的に間違っている可能性は高くありません。
例(一般的なAzure SQL Database向けの形):
Server=tcp:xxxx.database.windows.net,1433;
Initial Catalog=YourDatabase;
Persist Security Info=False;
User ID=YourUser;
Password=YourPassword;
MultipleActiveResultSets=False;
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=30;
それでも繋がらない場合に本当に見るべきは、次の2点です。
- Blazorアプリがどの環境(Development / Productionなど)として起動しているか
- アプリが参照している接続文字列(GetConnectionStringの戻り値)が、Azureポータルの内容と一致しているか
ここを飛ばして「ネットワーク?Azureの設定?SQL側?」と進むと、遠回りになりがちです。
Mac移行で起きやすい“設定ズレ”の典型パターン
appsettings.json と環境別JSONの読み込み順で、別の値が優先される
ASP.NET Coreでは、設定が複数経路から積み上がり、後から読まれたものが上書きされます。代表的な積み上げ順は次の通りです。
appsettings.jsonappsettings.{Environment}.json(例:appsettings.Development.json)- ユーザーシークレット(Developmentで利用されがち)
- 環境変数(コンテナ、CI、IDE設定で入りがち)
- コマンドライン引数
移行直後にありがちなのは、Mac側で ASPNETCORE_ENVIRONMENT が意図せず変わっていたり、起動方法(IDE / dotnet run / Docker)が変わって“読み込む設定の組み合わせ”が変化することです。
ファイル名の大文字小文字・配置の違いが、Macで表面化する
Macのファイルシステム設定や運用方法によっては、大文字小文字が厳密に扱われます。Windowsでは問題にならなかった、次のようなズレが原因になることがあります。
| ズレの例 | 起きる現象 | 結果として見える症状 |
|---|---|---|
appsettings.Development.json の綴りや大小が違う | 環境別設定が読み込まれない | 別の接続文字列が使われる/空の接続文字列で初期化される |
| プロジェクトの起動プロファイルが別になっている | 環境変数やURLが変わる | 想定外の設定ソースが優先され、接続先がズレる |
| ユーザーシークレットに古い接続文字列が残っている | JSONの修正が反映されない | 「直したのに変わらない」状態になる |
環境変数で接続文字列が上書きされている
.NETの設定は環境変数で簡単に上書きできます。たとえば接続文字列は次のような名前で設定されることがあります。
ConnectionStrings__DefaultConnectionConnectionStrings__AppDb
Mac移行時にシェル設定(zshの設定ファイル)やIDEのRun Configurationに環境変数が入り、気づかず上書きされているケースもあります。
最短で原因を特定するデバッグ手順
「推測」を減らして「観測」で潰すのが最短ルートです。以下の手順で、かなりの確率で接続失敗の根本が見つかります。
環境名の確認(Development/Production)
アプリ起動時に、現在の環境名をログへ出す(または起動ログで確認する)ようにします。環境名が想定と違うと、読み込む設定ファイルが変わります。
参照している接続文字列を“マスクして”ログ出力する
パスワードは出さず、次の情報だけでも十分です。
- 接続文字列キー名(例:DefaultConnection / AppDb)
- サーバー(ホスト名)
- データベース名(Initial Catalog)
ここで「思っていたサーバー名と違う」「DB名が違う」「空になっている」が出れば、接続文字列そのものではなく設定の参照経路が原因です。
ユーザーシークレットの確認
開発環境でユーザーシークレットを使っている場合、Windowsの“つもり”でMac側も同じ挙動だと思い込むのが危険です。Mac側のプロジェクトでシークレットに古い値が残っていると、JSONを書き換えても反映されません。
接続処理の発火点を確認(どのコードが接続しにいっているか)
Error 26が出た“瞬間”のスタックトレースを見て、接続しようとしている主体が何かを判断します。
- DbContext初期化(EF Core)なら:DbContext登録・キー名・設定の上書きが主戦場
- アプリ起動直後のログ初期化なら:Serilogなど周辺機能が主戦場
- ヘルスチェックやマイグレーションなら:起動時タスクの順序・例外の握り方が主戦場
接続文字列でありがちな“壊れ方”と対策
不可視文字(改行、全角空白、タブ)でホスト名が一致しない
コピペの過程で、ホスト名の末尾に不可視文字が入ると、DNS解決や接続先判定が崩れます。見た目では分かりません。
- 接続文字列を一度プレーンテキストへ貼り付けてから再コピーする
- サーバー名部分だけを抽出して再入力する
パスワードに記号が含まれていて解釈がズレる
パスワードに ; など区切り文字に見える記号が含まれる場合、接続文字列として正しく解釈されないことがあります。もし心当たりがあるなら、いったん記号を含まないパスワードへ変更して挙動を確認すると切り分けが早まります(運用ルールに従って実施してください)。
今回の真因:Serilogの設定ミスが“DB接続エラー”に見えていた
最終的に質問者の報告では、原因は Serilog(ログ出力ライブラリ)の設定ミス でした。ここがこの事例の最大の学びです。
なぜSerilogが原因だと「DBに繋がらない」に見えるのか
Serilogはログの出力先を柔軟に選べます。構成によっては、ログ保存先としてSQL Server(Azure SQL Database)を使います。その場合、アプリ起動時にSerilogが初期化され、ログ出力先のDBに対して接続・テーブル作成・書き込み確認などが走ることがあります。
ここで設定が少しでもズレていると、アプリ本体がDBアクセスを始める前に例外が発生し、結果として「BlazorアプリからDBに接続できない」という見え方になります。
Serilog起因を短時間で確定させる切り分け
ログ周りが怪しい場合は、次のように“最小構成で起動できるか”で判断すると速いです。
| 切り分け操作 | 狙い | 結果の解釈 |
|---|---|---|
| SerilogのDBシンク設定を一時的に外す(Console sinkのみ等) | ログ初期化が落としていないか確認 | 外すと起動するならSerilog設定が濃厚 |
| アプリ本体のDB接続処理だけを残して起動 | メインのDbContext/ADO.NETが正常か確認 | メインが繋がるなら“周辺機能がDB接続して落ちている” |
| 例外のスタックトレースで最初の発火点を見る | どのコンポーネントが接続しているか特定 | Serilogやシンク関連が出ていればほぼ確定 |
再発防止:アプリ本体DBとログDBのキーを分ける
「アプリのDB接続」と「ログ保存のDB接続」を同じキーで使い回すと、障害時に“どっちが壊れているか”が分かりにくくなります。用途別にキーを分けると、切り分けが劇的に楽になります。
| 用途 | 推奨キー例 | 設計の狙い |
|---|---|---|
| アプリ本体(EF Core / ADO.NET) | ConnectionStrings:AppDb | 必須リソースとして安定させ、起動時に必ず検証する |
| ログ保存(Serilog DB sink) | ConnectionStrings:LogDb | 失敗してもアプリ本体を止めない運用(フォールバック)を検討できる |
ログは重要ですが、ログが書けないだけでサービス全体が起動不能になるのは避けたい場面も多いです。特に移行直後は、ログ出力先を一度Console/ファイルに寄せて“まず動かす”運用に切り替えるのも有効です。
同じ症状のときに効くチェックリスト
「Azure Data Studioでは接続できるのに、アプリでは Error 26」という状況で、ムダ打ちを減らす確認順です。
| 確認順 | チェック内容 | 狙い |
|---|---|---|
| ネットワーク | Data Studio / nc / sqlcmd 等で同一ホストに到達できる | ここがOKならネットワークやAzure側の可能性は下がる |
| 実効接続文字列 | アプリが参照している接続文字列(キー名含む)が想定通りか | 「コピペした」ではなく「実際に使っている」を確定する |
| 設定の上書き | 環境別JSON、環境変数、ユーザーシークレットで上書きされていないか | Mac移行で最もズレやすいポイント |
| 発火点 | DbContextか、Serilogか、ヘルスチェックか、起動時処理か | “誰が接続しにいったか”で対策が変わる |
| 周辺ライブラリ | SerilogのDBシンク、起動時マイグレーション、初期化タスクを最小化して検証 | 本体と周辺機能の切り分けで、原因を一点に絞る |
まとめ:ツールで繋がるなら、疑うべきは「DB」より「アプリの設定と起動順」
今回のケースの核心は、Azure Data Studioでは繋がる=ネットワークやAzure SQLの基本は成立しているのに、BlazorアプリだけがError 26を出した点です。ここまで条件が揃うと、最優先で見るべきは「接続文字列そのもの」よりも、アプリが実際に参照している設定(実効値)と、どのコンポーネントが最初にDBへ接続しにいっているかです。
そして実例として、Serilogの設定ミスが“DB接続エラー”のように見えることがあります。移行作業では、アプリ本体の接続と周辺機能(ログ等)の接続を分離し、最小構成で動作確認→段階的に戻す流れにすると、同種のトラブルを短時間で収束できます。

コメント