SQL Server のログインエラー 18456 を業務SEが10分で剥がす — 原因別の最短対処
みなさんこんにちは!ヒロポンです!
客先で、昨日まで普通に動いてたアプリが急に落ちる。「ログインに失敗しました(Microsoft SQL Server、エラー: 18456)」。
開いてみても、原因はどこにも書いてない。ただ「失敗しました」とだけ。
パスワード?権限?DB?……手がかりゼロで詰む朝、ありませんか??
でもこれ、原因を一発で割る場所が決まってます。クライアントに出る 18456 は、わざと原因を隠してるだけ。サーバ側のログを見れば、State という数字で犯人が即わかります。
この記事は、その「ERRORLOG の State を見て原因別に最短で剥がす」手順を、業務SEが10分で回せるようにまとめます。
結論: クライアントの 18456 は原因を隠す。サーバの ERRORLOG の State を見る
先に答えです。
クライアント(アプリや SSMS)に返る 18456 は、セキュリティのために原因をわざと伏せて State を 1 に丸めています。
だからクライアント側をいくら睨んでも原因はわかりません。
本当の原因は、サーバの ERRORLOG に書かれている State の値です。Error: 18456, Severity: 14, State: 8. のように、ここだけ正しい State が出る。
この数字を見れば、パスワード違いなのか、ログインが無いのか、DB が開けないのかが一発で割れます。
つまり 18456 の対処は、「ERRORLOG を開いて State を読む」が起点。ここから始めれば、いい感じに10分です。
なぜクライアントには原因が出ないのか
理由はシンプルで、わざとです。
攻撃者に「ユーザー名は合ってるがパスワードが違う」「そのユーザーは存在しない」といったヒントを与えないため。SQL Server はクライアントに返すメッセージから原因をそぎ落とします。
Microsoft の公式ドキュメントにも、こう書かれています。
セキュリティを高めるため、クライアントに返されるエラーメッセージは認証エラーの性質を意図的に隠します。ただし SQL Server のエラーログには、認証失敗の条件に対応するエラー State が記録されます。
要するに「外(クライアント)には隠すけど、中(サーバログ)には本当のことを書いてある」。
だからサーバの ERRORLOG を見るのが正解ルートになります。
最短対処: ERRORLOG で本当の State を読む
ERRORLOG は SSMS から開いてもいいんですが、T-SQL で 18456 だけ絞って読むのがいちばん速いです。
-- ERRORLOG から 18456 の行だけ抜き出して、本当の State を見る
-- 第1引数 0 = 現在のログ / 第3引数で '18456' を含む行に絞り込み
EXEC xp_readerrorlog 0, 1, N'18456';
実行結果(State 8 / State 5 の行が見える):

State: 8 みたいな数字が見えれば勝ちです!!その数字を次の早見表と突き合わせれば、原因が確定します。
ちなみに、同じ「間違ったパスワード」でも、クライアントには State が一切出ません。
下が、クライアント側のそっけないメッセージと、ERRORLOG の State 8 の対比です。

ついでに、認証モードもよく原因になるので確認しておきます。
-- 1 = Windows 認証のみ / 0 = 混合モード(SQL認証も可)
SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') AS is_windows_only;
これが 1(Windows 認証のみ)なのに、アプリが SQL 認証で繋ごうとしていれば、それが原因(後述の State 58)です。
State 値別の原因と対処(早見表)
ERRORLOG で読んだ State を、この表で引いてください。よく出るやつを、こんな感じでまとめてあります。

切り分けの流れを図にすると、こんな感じです。

ハマりポイント
剥がす過程で踏みやすい罠を3つ。
① State を握り潰されてるのに気づかず、クライアント側を延々いじる
これがいちばん多い。アプリのエラーには State が出ない(出ても 1)ので、接続文字列やパスワードを当てずっぽうで直し続けて、半日溶ける。
先に ERRORLOG の State を読む。これだけで遠回りが消えます。
② 認証モードを混合に変えたのに、SQL Server を再起動していない
State 58(Windows 認証のみ)で、SSMS の「サーバのプロパティ → セキュリティ」で「SQL Server と Windows 認証モード」に変えた。でも繋がらない。
あれ、設定は合ってるのに??ってなりますが、原因は再起動忘れでした。認証モードの変更は SQL Server サービスを再起動して初めて効きます。
③ 混合モードに切り替えた直後の sa が、State 7 で無効のまま
Windows 認証のみで構築したインスタンスを後から混合モードに変えると、sa ログインは最初は無効のままです。
この状態で sa を使うと State 7(無効 + パスワード違い)になる。ALTER LOGIN sa ENABLE; で有効化して、パスワードも設定してから使います。
-- 混合モードに変えた直後の sa を使えるようにする
ALTER LOGIN sa ENABLE;
ALTER LOGIN sa WITH PASSWORD = 'ここに強いパスワード';
現場メモ
ここからは現場メモ。
俺が客先で 18456 を踏んだとき、最初の30分はずっとアプリ側を疑ってました。接続文字列、パスワード、ファイアウォール……。
クライアントには手がかりがゼロなので、当てずっぽうになるんですよね。直してはリトライ、直してはリトライ。じわじわ時間だけ溶ける。
抜け出せたのは、先輩の一言でした。「ERRORLOG の State 見た?」。
見たら State: 38。既定DBが復元中で開けなかっただけ、というオチ。アプリは1ミリも悪くなかった。
あの30分、まじでやらかした。
今だったら、18456 を見た瞬間に ERRORLOG へ直行します。
でもね、当時は「アプリのエラーなんだからアプリが悪い」っていう単純な式しか頭になかったんですよね。
それ以来、18456 を見たら何よりまず ERRORLOG の State、と体に叩き込みました。クライアントの曖昧なメッセージで悩む時間が、まるごと消えます。
障害対応は、見る場所さえ合っていれば短いんです。
まとめ
SQL Server 18456 の剥がし方、整理するとこうです。
- クライアントの 18456 は原因を隠している — State はセキュリティのため 1 に丸められる
- 本当の原因はサーバの ERRORLOG の State —
xp_readerrorlog 0, 1, N'18456'で一発 - State 8 はパスワード違い / 2・5 はログイン名なし / 38・46 は既定DBが開けない / 58 は認証モード不一致
- 認証モードを変えたら SQL Server の再起動を忘れない。混合化直後の sa は State 7 で無効
クライアントの曖昧なメッセージを睨む時間をやめて、最初に ERRORLOG を開く。これだけで 18456 は、いい感じに10分案件になります。
よくある質問
Q1. クライアントのエラーに State が出ません。どこで見るんですか?
サーバ側の ERRORLOG です。クライアントに返る 18456 はセキュリティのため State を 1 に丸めるので、原因は出ません。SQL Server に接続できる別アカウントがあれば EXEC xp_readerrorlog 0, 1, N'18456'; で、無ければサーバの LOG フォルダ(Linux なら /var/opt/mssql/log/errorlog)のファイルを直接開いて State を確認します。
Q2. State 8 と State 7 はどう違うんですか?
State 8 は「ログインは存在するが、パスワードが違う」です。State 7 は「ログインが無効、かつパスワードも違う」。State 7 は、Windows 認証で構築したインスタンスを混合モードに変えた直後の sa でよく出ます(sa が初期は無効のため)。
Q3. 認証モードを混合に変えたのに、まだ 18456 が出ます。
SQL Server サービスの再起動を忘れていませんか。認証モードの変更は、サービスを再起動して初めて反映されます。再起動後も State 7 が出るなら、対象ログイン(sa など)が無効のままか、パスワードが未設定の可能性が高いです。
Q4. 急に 18456 になりました。設定は何も変えていません。
設定変更なしで急に出るなら、State 38/46(既定DBが開けない)を疑ってください。既定DBがオフラインや復元中になると、ログイン自体は正しくても接続が弾かれます。ERRORLOG の State が 38 なら、対象DBの状態(ONLINE か)を確認するのが最短です。
関連記事
- SQL Server UPDATE … FROM SELECT 3パターン — 接続が通った後、データ更新を安全に書く話。JOIN / CTE / MERGE の使い分け
- SQL Server DISTINCT の3つの罠 — 同じく「本番でだけ挙動が変わる」系。重複排除の落とし穴
- SQL Server の一時テーブル・テーブル変数・CTE を使い分ける3つの判断軸 — 復旧後の確認クエリで一時退避を使うときの基礎
- SQL Server の CAST と CONVERT でハマる3箇所 — 接続できた後に踏む、地味な型変換の罠
- 「客先常駐しかない」業務SEが技術+αで抜ける道 — 障害対応を10分で剥がせる SE は、現場でどう評価が変わるか。手を動かす人のキャリア論
以上!
「18456 でアプリ側を延々疑った」経験ある人いたら、どんどんシェア待ってるぜ!!
執筆者
バイブス父さん — 業務SE 7年(SIer 正社員2 / フリーランス5)。現職は SEO 直轄部の AI アドバイザー兼 PL、副業で中小 SIer の CTO。SIer の正社員からフリーランスに転じ、複数のエージェント経由で案件を回してきた経験ベースで「業務SE視点」の技術 + キャリア記事を書いています。
🐦 X: @hiro_progra0524(日々の現場メモ更新中)
📝 About Me で経歴詳細を見る


コメント