☰
SQL Server 18456错误排查指南:状态码解析与修复方法
2026/10/11 3:09:30 网站建设 项目流程

遇到 SQL Server 登录报 18456,我估计每一位 DBA 和做后端开发的同事都经历过几个不眠之夜。你可能会看到两种完全不同的现象:一种是客户端直接弹一个“用户 ‘sa’ 登录失败”,另一种是错误日志里一大段文字,看得人头大。其实 18456 这个错误码本身只是一个“壳子”,真正决定问题方向的是它后面跟着的状态码。只要会读状态码,80% 的登录问题都能在几分钟内定位,剩下的就是按方子抓药的事。

这篇文章我会把 18456 错误的来龙去脉讲透,包括状态码怎么读、错误日志去哪里翻、每种状态码背后的修复步骤,以及我这些年实际踩过的坑。不管你是刚接手 SQL Server 的新手运维,还是被测试环境折腾到怀疑人生的开发同学,只要你手里有能登录操作系统的权限,照着下面的方法一步步来,基本都能解决。

1. 先搞清楚报错“身份”:状态码和错误日志怎么读

1.1 为什么都是18456,原因可能完全不一样

很多人在搜索引擎里输入“SQL Server 18456”,然后照着网上说的“启用混合身份验证模式”“重置 sa 密码”试了一圈,结果问题没解决。原因很简单:18456 只是一个总错误号,就像医院里的“发热门诊”,引起发热的原因可能是感冒、可能是肺炎、也可能是其他问题,你得先分诊。

SQL Server 真正告诉我们“病因”的,是错误消息里打印出来的状态码。我整理了一份日常最高频的状态码对照表,建议你收藏起来:

状态码含义最常见的场景
1错误信息本身的问题,或信息不足极少见,先看完整错误日志
2无效的用户标识登录名不存在,或连接串写错了登录名
5无效的用户标识或密码密码错误、账号不存在、认证模式不匹配
6尝试使用已禁用的登录名sa 被禁用,或新建的 SQL 登录名是禁用状态
7登录名已锁定连续输错密码,触发了账户锁定策略
8密码已过期开启了密码过期策略
9密码必须更改强制修改密码后尚未修改
11有效登录,但服务器访问失败登录名没有 CONNECT 权限,或服务器处于特殊状态
12登录名被映射到了禁用的凭据证书/对称密钥映射类问题
18密码必须更改,请求不被允许密码策略与账户状态冲突

这里要注意,你从 SSMS 图形界面上看到的“错误: 18456”并不带状态码,真正带状态码的是 SQL Server 错误日志和 Windows 事件日志中的原文。所以第一步不是去乱改配置,而是先打开错误日志,把里面那行带状态码的记录捞出来。

1.2 三分钟找到SQL Server错误日志的原文

SQL Server 错误日志的默认位置一般在安装目录的 Log 文件夹下,比如 SQL Server 2019 默认实例的路径是:

C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Log\ERRORLOG

注意实例名不同,中间的目录名也会不一样。MSSQL15 对应 2019,MSSQL14 对应 2017,MSSQL16 对应 2022。如果你不确定路径,最简单的办法是在 SSMS 里连接上服务器(哪怕用 Windows 身份),在“管理→SQL Server 日志”里直接查看当前日志。但很多时候我们就是登录不上才来排查,所以直接用记事本打开 ERRORLOG 文件更靠谱。

打开文件后,拉到最底部,找包含 “Login failed” 的行。一个典型的登录失败记录长这样:

2025-01-06 23:15:31.01 Logon 错误: 18456,严重性: 14,状态: 5。 2025-01-06 23:15:31.01 Logon 登录失败。原因: 为所提供的登录名提供的密码不匹配。[客户端: 192.168.1.101]

看到状态: 5和密码不匹配,就可以放心往密码和认证模式方向去查了。再比如:

错误: 18456,严重性: 14,状态: 6。 登录失败。原因: 尝试使用禁用的登录名。 [客户端: 192.168.1.101]

这就是典型的状态 6,登录名被禁用了。

补充一个关键点:错误日志里的 [客户端: xxx] 表示连接的来源 IP,如果显示的是本地 IP 或者 127.0.0.1,说明请求是本机发出的。这能帮我们判断是客户端连不上,还是服务端在拒绝认证。

2. 动手改配置前,先做好这些基础检查

2.1 服务真的在监听吗?端口和协议排查

有一次帮朋友看问题,他折腾了半天 sa 密码,最后我发现数据库服务压根没起来。所以在看认证之前,先确认三件事:服务是否在运行、网络协议是否启用、端口是否正常监听。

先打开 Windows 服务管理器(services.msc),找到以 SQL Server (实例名) 开头的服务,确认状态是“正在运行”。如果服务没起来,后面的所有排查都白搭。服务正常之后,打开 SQL Server 配置管理器,展开“SQL Server 网络配置”,找到对应实例的协议,确认 TCP/IP 是“已启用”状态。SQL Server 默认安装时,TCP/IP 协议有时是禁用状态,尤其是仅安装了数据库引擎、没做网络配置的机器,本地能用 Windows 身份连,远程一律 18456。

TCP/IP 启用后,还需要确认端口。默认实例一般监听 1433,命名实例默认动态端口。在配置管理器的“TCP/IP 属性→IP 地址→IPAll”里,可以找到 TCP 动态端口和 TCP 端口。如果要固定端口,就把“TCP 动态端口”里的值清空,在“TCP 端口”里填 1433,然后重启 SQL Server 服务。

验证端口是否真的在监听,用命令:

netstat -ano | findstr 1433

如果看到LISTENING状态,说明端口没问题。没看到的话,要么 TCP/IP 协议没启用,要么服务没起来,要么端口被改了。这时候再去翻协议设置。

还要提一嘴 SQL Server Browser 服务。如果你用的是命名实例(比如计算机名\SQLEXPRESS),客户端需要通过 Browser 服务的 UDP 1434 端口获得实例的端口号。这个服务默认可能是“手动”或“已停止”,连不上时记得确认它已经启动。

2.2 身份验证模式到底选的哪个?

这是 18456 里最常被忽略的一个原因。SQL Server 安装默认是“Windows 身份验证模式”。在这种模式下,你用 sa 或其他 SQL 账号登录,不管密码敲得多正确,服务端都直接拒绝,错误日志里的状态码通常是 5,但真实原因并不是密码错了,而是服务端根本不认 SQL 登录这种认证方式。

查看当前认证模式,可以用 SSMS 登录后右键服务器属性,在“安全性”页签里看“服务器身份验证”。如果是“Windows 身份验证模式”,那就说明问题出在这里。

改成混合模式的操作路径:SSMS → 右键服务器 → 属性 → 安全性 → 选“SQL Server 和 Windows 身份验证模式” → 确定。改完之后,必须重启 SQL Server 服务才能生效。这一步千万别忘,我见过有人改完不重启,然后继续怀疑人生。

如果你不方便用图形界面,注册表也可以改。SQL Server 的认证模式存在这里:

HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQLServer\LoginMode

LoginMode 的值是 1 表示仅 Windows 认证,2 表示混合认证。改成 2 后同样要重启服务。

2.3 连接的账号本身状态完整吗?

认证模式没问题之后,就该看登录名本身了。SQL Server 里一个 SQL 登录名有几项属性会直接导致 18456:

  • 禁用状态(is_disabled)
  • 密码是否过期(is_expiration_checked)
  • 是否被锁定(LOGINPROPERTY 查询)
  • 是否被强制修改密码(IsMustChange)

用 Windows 身份先连上数据库,执行下面这条 SQL,就能把用户的状态一次性看明白:

SELECT name, is_disabled, is_policy_checked, is_expiration_checked, LOGINPROPERTY(name, N'IsLocked') AS is_locked, LOGINPROPERTY(name, N'IsMustChange') AS must_change_password FROM sys.sql_logins WHERE name = N'sa';

网上很多教程直接告诉你“用 ALTER LOGIN sa WITH PASSWORD ‘xxx’ 重设密码”,但忽略了用户是否禁用、是否被锁。如果 is_disabled 是 1,光改密码是没用的,还得显式执行一次启用操作。后面我会把每条状态码对应的处理步骤单独列出来,你照着做就行。

3. 按状态码对症下药:把每种“死法”都救活

3.1 状态5或状态2:账号或密码不对,可背后还有5种情况

状态 5 是出现频率最高的一种,错误日志原文通常写着“密码不匹配”或者“为所提供的登录名提供的密码不匹配”。但我在实际排查中发现,状态 5 背后往往藏着好几种不同的根因:

  • 密码确实输错了。
  • 登录名写错了,比如把sa写成了admin,或者连接串里账号带了多余的空格。
  • 服务器认证模式是仅 Windows,SQL 登录被直接拒绝。
  • 客户端和服务端之间加密 TLS 设置不匹配,导致认证握手失败。
  • 密码里的特殊字符没有正确转义。

前两种好办,重新确认账号密码就行。第三种按上一节改成混合认证并重启。第四种在较新的 SQL Server 版本里容易遇到,特别是客户端用了新版驱动时默认启用了强制加密,而服务端没有配置证书。这时候错误可能表现为状态 5,但错误日志里往往还有一条关于证书或 SSL 的记录。可以先在连接字符串里加TrustServerCertificate=True,或者把驱动的 Encrypt 改成 Optional 再试。

第五种常见于在应用配置文件里写连接串时,密码包含;、'、"之类字符。比如:

Server=192.168.1.10;User Id=sa;Password=abc;123

分号会把连接字符串截断,导致密码解析成abc,自然就报密码不匹配。解决办法是把密码单独放到配置项,或者用 .NET 的 SqlConnectionStringBuilder 来拼接。

真正的“忘记 sa 密码”情况,只要你有 Windows 管理员权限,还是能救回来的。以管理员身份打开命令提示符,把 SQL Server 服务以单用户模式拉起来,然后重置 sa 密码。操作步骤我会在第 4 节里完整展开。

3.2 状态6、状态7、状态8、状态9:禁用、锁定、密码过期,一套命令全搞定

这几个状态码放在一起说,因为它们的处理逻辑是相通的,都是“账号本身活着,但状态不让用”。

状态 6 表示登录名被禁用。常见于安装后从未启用过 sa,或者 DBA 出于安全考虑禁用了某个应用账号。修复命令:

ALTER LOGIN [sa] WITH PASSWORD = N'新密码', CHECK_POLICY = OFF; ALTER LOGIN [sa] ENABLE;

如果不想改密码,只想启用:

ALTER LOGIN [sa] ENABLE;

状态 7 是账户被锁定。SQL Server 的密码策略里如果开启了“账户锁定阈值”,连续多次失败登录后账户会被锁。查询锁定状态用上面提到过的 LOGINPROPERTY,解锁命令:

ALTER LOGIN [sa] WITH UNLOCK;

解锁后建议顺手确认一下密码策略配置是否合理。如果业务上确实存在暴力破解风险,阈值可以保留,但别设得太小,否则一个手滑的脚本就能把生产账号锁干净。

状态 8 是密码过期,状态 9 是必须更改密码。这俩通常出现在开启了密码过期策略的数据库上,或者管理员在创建登录名时勾选了“强制密码过期”。修复方式就是改密码:

ALTER LOGIN [sa] WITH PASSWORD = N'新密码';

如果密码策略限制太死,你可以像上面那样在修改时加CHECK_POLICY = OFF和CHECK_EXPIRATION = OFF,但生产环境我不建议这么做,密码策略的初衷是安全,不是给我们添堵的。

3.3 状态11或状态12:登录名没问题,但没进门的资格

状态 11 很多人不熟。这个状态的意思是:服务端已经验证了你的账号密码,也认可你是合法登录名,但因为某些原因不让你进门。

最常见的情况是登录名缺少CONNECT SQL权限。SQL Server 里每个登录名必须拥有连接数据库引擎的权限,默认情况下 sysadmin 角色和 public 角色可以连接。如果某个登录名被显式拒绝,或者服务器角色被改得比较迷,就会看到状态 11。修复方式是在“登录名属性→安全对象”里授予“连接 SQL”权限,或者用脚本:

GRANT CONNECT SQL TO [你的登录名];

还有一种特殊情况:SQL Server 启动时加了-m单用户参数。单用户模式下系统只允许一个连接,其他连接请求会以状态 11 被拒绝。如果确认服务器处于单用户模式(可以通过 SQL Server 配置管理器查看启动参数),等维护结束把-m参数去掉并重启服务即可。

状态 12 相对少见,它和证书、对称密钥映射有关。如果你不是在做“凭据映射”相关的高级配置,基本不用担心这个状态码。真遇到了,先回顾最近有没有做过证书切换或恢复,然后检查对应证书的有效期。

3.4 其他少见状态码:遇到也别慌

状态 1、状态 2、状态 40、状态 46 这些属于低频状态码。状态 1 常常伴随着错误日志本身不完整,优先去 Windows 事件查看器里捞更多细节。状态 40 和 46 疑似和 TLS 加密协商相关,建议检查 SQL Server 的 TLS 配置、客户端驱动版本以及是否安装了最新的累积更新。总原则是:先看完整日志原文,再看服务端和客户端两端的通信协议,不要盲目改密码。

4. 从报错到修复:一次典型故障排查实录

4.1 故障现象:SQL客户端爆出18456,Windows认证却正常

之前有朋友的公司内部系统突然连不上测试库,SQL Server 的 sa 登录报 18456,但用 Windows 身份认证却能顺利连上。一开始他以为是 sa 密码被人改了,找我帮忙。我先在本地用 Windows 身份连上数据库,执行了认证模式查询,发现服务器身份验证确实是混合模式,密码对不上这一条就被排除了大部分。

接着我打开错误日志,看到里面的记录是:

错误: 18456,严重性: 14,状态: 5。 登录失败。原因: 为所提供的登录名提供的密码不匹配。

但蹊跷的是,这个报错记录对应的客户端 IP 是测试机本身的 IP,也就是说有人在测试机上用 sa 登录,但密码不匹配。我让他自己在测试机上用 sqlcmd 再试一次,并确认输入的密码和运维手里记录的密码是否完全一致。

4.2 排查步骤的递进思路:从日志一行开始定位

后来发现,问题就出在运维那边保存密码时多了一个空格。这个事听起来很蠢,但确实发生过很多次——密码在 Excel、备忘录、邮件转发过程中被自动加了个空格,复制到配置文件里完全看不出来。用 sqlcmd 手动输入密码后,连接成功。

这里我想强调的是排查思路的递进:看到 18456,先不急着改密码,第一件事永远是看日志里的状态码和原因描述;第二件事是确认认证模式;第三件事才是验证账号密码。顺序反了,很容易做出“无效修改”,甚至把原本正常的配置搞坏。

在这个案例里,如果一开始就按网上说的“重置 sa 密码”操作,虽然也能解决问题,但会造成一次不必要的密码变更,所有依赖 sa 的应用都得跟着改。而从日志和认证模式入手,只花了五分钟就定位到是“密码复制多了空格”。

4.3 如果手里只剩sa密码,又没有Windows管理员怎么办

这是最麻烦的场景,但也不是完全没有办法。如果操作系统管理员权限也没了,那就比较棘手,因为 SQL Server 的恢复逻辑依赖 Windows 权限。这里我假设你至少还有 Windows 管理员权限,只是 sa 密码彻底失传。

以管理员身份打开命令提示符,先把 SQL Server 服务停掉:

net stop MSSQLSERVER

然后以单用户模式启动:

net start MSSQLSERVER -m

注意,-m参数会限制为单用户连接,且默认只允许本地连接。启动完成后,另开一个命令提示符,用 Windows 身份连接:

sqlcmd -S . -E

连接成功后,在 sqlcmd 里重置 sa 密码:

ALTER LOGIN [sa] WITH PASSWORD = N'你的新密码', CHECK_POLICY = OFF; ALTER LOGIN [sa] ENABLE; GO

执行完GO后退出 sqlcmd,然后重启服务,这次不要带-m参数:

net stop MSSQLSERVER net start MSSQLSERVER

最后用新密码连接验证。需要提醒的是,单用户模式下如果连接不释放,其他连接是进不来的。如果你在 sqlcmd 窗口挂太久,记得及时退出。我在实际操作中习惯执行完脚本立刻exit,避免占用连接导致自己把自己锁在门外。

4.4 如果Windows身份也登不上:旧账重提的恢复方案

如果你连 Windows 身份都连不上,一种可能是当前 Windows 用户不在任何 sysadmin 角色的成员列表里。这种情况只能通过单用户模式 + 管理员操作系统权限恢复,思路和上面一样,但是登录时要用-E选项。SQL Server 在单用户模式下会允许本地 Windows 管理员作为 sysadmin 登录,这也是微软留下的后门通道。恢复后第一时间把当前 Windows 用户加到 sysadmin 服务器角色,然后重新启动正常模式。

这一步的操作意图很明确:在没有任何可用 SQL 登录名的情况下,借助操作系统的管理员身份强制进入实例,重置 sa 密码或修复合法的管理员登录名。整个过程要小心别在生产库上执行错了命令,最好先在测试环境演练一遍。

5. SQL Server登录失败排查速查表与避坑指南

5.1 五分钟快速判断问题域的思路

遇到 18456 不用慌,按照下面这个三步法走:

  1. 看状态码:从 SQL Server 错误日志或 Windows 事件日志里找到 18456 对应的状态码。
  2. 看日志原文:找到“原因”后面的描述,比如“密码不匹配”“禁用”“锁定”。
  3. 对表定位:结合状态码和描述,确定是认证模式类、账号状态类还是权限类问题。

只要状态码读对了,至少能节约半小时的盲目排错时间。我在处理其他同事提交的问题时,通常让同事先截图错误日志原文,配合状态码基本能直接给出处理方向。

5.2 常见问题速查表

现象状态码可能原因处理建议
sa 登录报 18456,原因“密码不匹配”5密码错误 / 认证模式不匹配 / 密码含特殊字符确认密码,检查认证模式,检查连接串转义
sa 登录报“禁用的登录名”6sa 或登录名被禁用ALTER LOGIN [sa] ENABLE
连续输错密码后被锁7触发账户锁定策略ALTER LOGIN [sa] WITH UNLOCK
登录报“密码已过期”8密码策略过期修改密码
登录报“密码必须更改”9强制密码修改修改密码,或调整密码策略
本地 Windows 能连,远程 184565/11TCP/IP 未启用 / 防火墙未放行 / 端口没监听启用 TCP/IP,固定端口,放行防火墙
应用连不上,报 18456,日志有 SSL 相关5TLS 配置不匹配连接串加 TrustServerCertificate=True
SQL 登录被拒绝11缺少 CONNECT SQL 权限GRANT CONNECT SQL TO 登录名

这张表只覆盖了高频场景。如果你想把它变成自己的排查武器,建议把表里的状态码和原因描述抄到自己的笔记里,下次报错时对照着看,效率翻倍。

5.3 新手最容易踩的5个坑

第一,改完认证模式不重启服务。很多人在 SSMS 里切换成混合模式后直接测试,发现还是 18456,然后怀疑自己操作错了。实际上认证模式的改动必须重启 SQL Server 服务才生效。

第二,启用 TCP/IP 后不重启服务或不停在配置里固定端口。TCP/IP 协议启用后同样需要重启服务,动态端口如果不固定,客户端下次连接可能找不到入口。

第三,密码重置后不检查“禁用”状态。sa 或某个 SQL 登录名在重置密码后仍然是禁用状态,你以为是密码问题,实际是禁用问题。

第四,防火墙只开了 1433 端口,却忽略了命名实例需要 UDP 1434。如果你连的是命名实例,只开 1433 不够,SQL Server Browser 服务的 UDP 1434 也要放行。

第五,把生产库的密码策略直接关掉。有些同学图省事,修改 sa 密码时把所有策略都关掉,结果生产环境的安全审计被打穿。我的建议是:即使要临时关闭,事后也要恢复合理的密码策略。

5.4 我的两个独家小技巧

技巧一:在测试环境里故意制造一次 18456 错误,然后去错误日志里找对应记录。这个方法对新手特别管用,你可以亲手感受一下“状态码 5”和“状态码 6”在日志原文中的区别。一旦你见过真实的日志格式,以后再遇到就不会慌。

技巧二:使用 sqlcmd 命令验证连接时,加上-l参数控制登录超时,避免因为网络问题一直卡在那里。一个标准的测试命令是:

sqlcmd -S 192.168.1.10 -U sa -P '你的密码' -l 5

如果本地 sqlcmd 测试通过,但程序连接失败,问题基本出在连接串或驱动的配置上。如果本地测试也失败,那就老老实实按状态码去排查服务端。

我之前处理过一个最复杂的案例,本地 sqlcmd 能连、本机程序也能连,偏偏远程程序连不上。后来查出来是服务器上配置了多个 IP,SQL Server 监听的是其中一个内网 IP,而客户端访问的是另一个 IP。这种问题排查到最后已经不是 18456 本身能解决的了,需要结合网络拓扑和 SQL Server 监听地址一起看。遇到这种概率很低的配置问题时,别钻牛角尖,先检查服务监听地址是否与客户端访问地址一致。

最后再分享一点个人体会:SQL Server 的 18456 错误是数据库维护工作中最常见的登录类错误之一,但它从来不是“玄学”。它的背后永远是具体的配置状态、账号状态、网络状态和权限状态。读日志、看状态码、按步骤排查,这套流程走完,绝大多数问题都能迎刃而解。希望这篇内容能帮你少走几步弯路,尤其是在那些让人容易忽视的细节上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询