SQL Server のログインエラー 18456 を業務SEが10分で剥がす — 原因別の最短対処

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 の行が見える):

xp_readerrorlog で 18456 行を抜き出し、State 8(パスワード違い)や State 5(ログイン名なし)が見える実行結果

State: 8 みたいな数字が見えれば勝ちです!!その数字を次の早見表と突き合わせれば、原因が確定します。

ちなみに、同じ「間違ったパスワード」でも、クライアントには State が一切出ません。

下が、クライアント側のそっけないメッセージと、ERRORLOG の State 8 の対比です。

間違ったパスワードでログインすると、クライアントには汎用メッセージだけが返り、ERRORLOG には State 8 が記録される対比の実行結果

ついでに、認証モードもよく原因になるので確認しておきます。

-- 1 = Windows 認証のみ / 0 = 混合モード(SQL認証も可)
SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') AS is_windows_only;

これが 1(Windows 認証のみ)なのに、アプリが SQL 認証で繋ごうとしていれば、それが原因(後述の State 58)です。

State 値別の原因と対処(早見表)

ERRORLOG で読んだ State を、この表で引いてください。よく出るやつを、こんな感じでまとめてあります。

SQL Server 18456 の State 値ごとの意味と最短対処をまとめた表。State 2/5 はログイン名なし、7 は無効+パスワード違い、8 はパスワード不一致、38/46 は既定DBが開けない、58 は認証モード不一致

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

クライアントに18456が出たら、サーバのERRORLOGを開いてState値を確認し、2/5はログイン名なし、7は無効+パスワード違い、8はパスワード不一致、38/46は既定DBが開けない、58は認証モード不一致へ分岐する切り分けフロー

ハマりポイント

剥がす過程で踏みやすい罠を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 の Statexp_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 か)を確認するのが最短です。

関連記事

以上!

「18456 でアプリ側を延々疑った」経験ある人いたら、どんどんシェア待ってるぜ!!


執筆者

バイブス父さん — 業務SE 7年(SIer 正社員2 / フリーランス5)。現職は SEO 直轄部の AI アドバイザー兼 PL、副業で中小 SIer の CTO。SIer の正社員からフリーランスに転じ、複数のエージェント経由で案件を回してきた経験ベースで「業務SE視点」の技術 + キャリア記事を書いています。

🐦 X: @hiro_progra0524(日々の現場メモ更新中)
📝 About Me で経歴詳細を見る


この記事が気に入ったら
いいねしてね!

どんどんシェア待ってるぜ!!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次