MySQL · 错误码速查
MySQL 错误 1045:连接时身份验证没通过,先看报错里的用户、来源主机和 using password
1045 是连接阶段的拒绝:服务器在账号表里没找到能匹配“这个用户名 + 这台来源主机 + 这个密码”的账号。报错本身已经告诉你三件事:你以什么用户登录、从哪台主机连、有没有带密码(using password: YES/NO)。按这三项逐个对,通常比反复改密码更快。
官方原文
Access denied for user '%s'@'%s' (using password: %s)三个 %s 依次是:你登录用的用户名、服务器看到的客户端主机、是否带了密码(YES / NO)。官方原文:“The Access denied error message tells you who you are trying to log in as, the client host from which you are trying to connect, and whether you were using a password.”
出处:MySQL 8.4 Error Reference:Server Error Message Reference 最后核对:
| 错误号 / 符号 | 1045 / ER_ACCESS_DENIED_ERROR | 出处 |
|---|---|---|
| SQLSTATE | 28000 | 出处 |
| 发生阶段 | 访问控制第 1 阶段:连接验证(先查凭据,再查账号是否锁定) | 出处 |
| 账号匹配依据 | mysql.user 表的 Host + User 列,按“最具体的 Host 优先”排序后取第一条匹配 | 出处 |
| 相邻错误 | 1044 库级权限不足(42000);1130 主机不允许连接;1251 客户端不支持服务器要求的认证协议(08004) | 出处 |
先读懂报错里的三个信息
| 报错里看到的 | 官方文档给的含义 | 先查什么 |
|---|---|---|
'root'@'localhost' (using password: NO) | 没带密码就登录。新装的 MySQL 如果安装时已经给 root 设了密码,就会这样报。 | 用 mysql -u root -p 带上密码;不知道密码看官方“Securing the Initial MySQL Account”和“How to Reset the Root Password”。 |
(using password: YES) | 带了密码,但密码不对。 | 如果你根本没在命令行写密码却出现 YES,说明某个选项文件(option file)里写了旧密码。 |
'root'@'' 或 ''@'unknown' | 服务器解析客户端主机名时出了问题(DNS)。 | 官方给的办法:mysqladmin flush-hosts 清主机缓存;长期方案包括授权表里用 IP 而不是主机名、或在 /etc/hosts 加记录、或启用 skip_name_resolve。 |
排除选项文件干扰的办法是加 --no-defaults,例如 mysqladmin --no-defaults -u root version:客户端就不会读任何选项文件里的用户名和密码。
服务器怎么挑账号:最具体的 Host 先匹配
同一个连接可能同时匹配 mysql.user 里的多行。服务器读入账号表时会先排序:Host 越具体越靠前(字面 IP 和主机名最具体,% 最不具体,空字符串 '' 排在 % 之后);Host 相同时,非匿名用户排在匿名用户(User 为空)前面。连接时用排序后的第一条匹配。
官方专门提醒了一个常见误解:不是“写了我用户名的行优先”。例如表里同时有 ''@'localhost'(匿名用户)和 'jeffrey'@'%',jeffrey 从本机连接时会先匹配到匿名那一行,于是按匿名用户的密码规则验证,结果就是 1045。官方给的正确做法是另建一行 'jeffrey'@'localhost',或删掉 ''@'localhost' 这行匿名账号。
连上以后想确认服务器到底把你当成了哪个账号,用 CURRENT_USER();它返回的是匹配到的那一行的 User@Host。USER() 返回的是你连接时声明的用户名和客户端主机,两者不一定相同。
按现象对号入座
| 现象 | 官方文档给的原因 |
|---|---|
| 报错里的来源主机和 user 表 Host 列写法对不上 | user 表里写的是短名(如 pluto),DNS 告诉 MySQL 的却是完整域名 pluto.example.com(或反过来),这一行就不生效;官方建议加一行用你主机 IP 作 Host 的账号。 |
在服务器本机 mysql -u 用户 能连,从远程客户端 mysql -h 主机 -u 用户 不行 | 没有为这个用户名开放从那台远程主机访问。 |
mysql -u 用户 能连,mysql -u 用户 某个库 不行 | 这个用户没有那个库的权限(这种情况对应 1044,不是 1045)。 |
命令行 mysql 客户端能连,PHP / Python / Java 程序连不上 | 问题在程序的连接参数,不在账号权限。 |
| 直接改了授权表(INSERT / UPDATE)却不生效 | 需要执行 FLUSH PRIVILEGES 让服务器重新加载;用 CREATE USER / ALTER USER / GRANT 则不需要。 |
用有权限的账号做只读核对
SELECT USER(), CURRENT_USER();
-- 把 'app' 换成报错里的用户名;空字符串那一行是匿名账号
SELECT Host, User, plugin, account_locked
FROM mysql.user
WHERE User IN ('app', '')
ORDER BY User, Host;
SHOW GRANTS FOR CURRENT_USER();plugin 列是这个账号用的认证插件,account_locked 为 Y 时账号被锁定,凭据正确也连不上。官方提醒:authentication_string 列存的是加密后的密码,“从服务器角度看加密后的密码就是真正的密码”,不要给非管理员读 mysql 系统库的权限,所以上面的查询故意没选这一列。(Connection Verification)
哪些报错看起来像 1045,其实不是
| 错误 | 原文(MySQL 8.4 错误参考) | 和 1045 的区别 |
|---|---|---|
1044 ER_DBACCESS_DENIED_ERROR | Access denied for user '%s'@'%s' to database '%s' | 已经通过连接验证,只是对某个库没权限。 |
1130 ER_HOST_NOT_PRIVILEGED | Host '%s' is not allowed to connect to this MySQL server | user 表里根本没有能匹配这台客户端主机的 Host 行。 |
1251 ER_NOT_SUPPORTED_AUTH_MODE | Client does not support authentication protocol requested by server; consider upgrading MySQL client | 客户端太旧,生成不了服务器要求的密码格式。 |
3955 ER_USER_ACCESS_DENIED_FOR_USER_ACCOUNT_BLOCKED_BY_PASSWORD_LOCK | Access denied for user '%s'@'%s'. Account is blocked for %s day(s) (%s day(s) remaining) due to %u consecutive failed logins. | 账号因连续输错密码被临时锁定,锁定期内密码正确也进不去。 |
临时锁定只有在账号的 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 都不为 0 时才会发生;CREATE USER 不写这两项时默认都是 0,也就是不开启。计入失败次数的只有“密码不对”,用户名不存在或网络问题不算。(Password Management)
两条官方也提醒过的风险
- 为了先连上把 Host 设成
%:官方建议连上后用SELECT USER()看清真实来源主机,再把%改成实际主机名,“否则系统就处于不安全状态”。 --skip-grant-tables启动:官方把它写在 “For testing purposes” 之下,用来验证授权表修改是否生效,改完要正常重启。我们建议只在隔离环境里这样做。
常见问题
mysql 1045 错误是什么意思?
1045(ER_ACCESS_DENIED_ERROR,SQLSTATE 28000)表示连接时身份验证没通过:没有一行账号能同时匹配你的用户名、来源主机和密码。
mysql 1045 using password: YES 是什么原因?
YES 表示客户端带了密码但不对。如果你没在命令行输入密码也看到 YES,多半是选项文件里写了旧密码,可以用 --no-defaults 排除。另一种可能是你被匹配到了别的账号行(例如匿名账号),用 CURRENT_USER() 能确认。
using password: NO 怎么办?
说明这次连接没带密码。新装的 MySQL 如果安装时已给 root 设了密码,用 mysql -u root 就会报 1045 (using password: NO);改用 mysql -u root -p 并输入密码。
本地能连、远程连不上报 1045 怎么办?
官方的解释是没有为这个用户开放从那台远程主机访问的账号。看 mysql.user 里这个用户名有哪些 Host 行;如果连 Host 都不匹配,报的通常是 1130 而不是 1045。
Navicat 等客户端连接 MySQL 报 1045 怎么办?
先用命令行 mysql 客户端以同样的用户名、主机和密码连一次。官方的判断方法是:命令行能连、程序连不上,问题在程序的连接参数;命令行也不行,再按本页的三个信息逐项核对账号。
下一步
价格以对应页面当前标价为准。
出处(最后核对 2026-10-28)
- MySQL 8.4 Error Reference:Server Error Message Reference
- MySQL 8.4 Reference Manual 8.2.22:Troubleshooting Problems Connecting to MySQL
- MySQL 8.4 Reference Manual 8.2.6:Access Control, Stage 1: Connection Verification
- MySQL 8.4 Reference Manual 8.2.15:Password Management(Failed-Login Tracking and Temporary Account Locking)
- MySQL 8.4 Reference Manual B.3.2.1:Access denied
本页摘录并解读上面列出的官方文档,不是官方页面;官方文档更新后以官方为准。本页内容都来自官方文档,没有我们自己的测试结果。