答案是客户端不支持caching_sha2_password插件,需执行SELECT user,host,plugin FROM mysql.user WHERE user='your_username'确认plugin值,若为caching_sha2_password且使用Navicat 15以下、PHP 7.4及更早或PyMySQL等旧客户端,则应ALTER USER切换为mysql_native_password并FLUSH PRIVILEGES。

MySQL 8.0 连不上,八成不是密码错了,而是客户端压根不认识 caching_sha2_password ——握手阶段直接中断,报错如 ERROR 2059、Authentication plugin 'caching_sha2_password' cannot be loaded 或 mysqli_real_connect(): the server requested authentication method unknown to the client。
怎么确认是 caching_sha2_password 搞的鬼
先用能连上的方式(比如 mysql -u root -p)登录 MySQL 命令行,执行:SELECT user, host, plugin FROM mysql.user WHERE user = 'your_username';
重点看 plugin 列值。如果显示 caching_sha2_password,且你用的是以下任一环境,基本就是它:
- Navicat 15 以下版本
- PHP 7.4 及更早(尤其宝塔、phpEnv 默认包)
- PyMySQL
- JDBC Connector/J
- Django 3.0 以下默认配置
注意:'root'@'localhost'、'root'@'127.0.0.1'、'root'@'%' 是三个完全独立的用户,必须分别查、分别处理。
ALTER USER 切换插件时必须满足的硬性条件
这是最常用、见效最快的方式,但漏掉任意一条都会失败或锁死账户:
- 必须显式指定密码:只写 IDENTIFIED WITH mysql_native_password 不带 BY 'xxx',原密码会被清空
- host 必须完全匹配:Navicat 默认走 TCP(即 127.0.0.1),不是 localhost;Docker 内连宿主机常是 'appuser'@'172.17.0.1',不能笼统写 '%'
- 执行后必须立刻跟 FLUSH PRIVILEGES;:部分 MySQL 8.0.x(尤其是云 RDS 小版本)不执行这句就不生效
- 示例(按需组合):ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MyPass123!';ALTER USER 'root'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'MyPass123!';ALTER USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'AppPass@2026';
为什么改 my.cnf 的 default_authentication_plugin 不管用
这个配置项只影响「之后新建的用户」,对已存在的用户(包括安装时创建的 root)完全无效:
- 即使你加了 [mysqld] default_authentication_plugin = mysql_native_password 并重启 MySQL,root 的 plugin 字段仍是 caching_sha2_password
- Docker 启动时加 --default-authentication-plugin=mysql_native_password 同样不修复存量用户
- 云数据库(如阿里云 RDS)通常禁止修改配置文件或重启,这条路根本走不通
- 若遇到 ERROR 1524: Plugin 'mysql_native_password' is not loaded,说明插件本身未启用:先查 SHOW PLUGINS WHERE Name = 'mysql_native_password';,状态非 ACTIVE 则需重装完整服务端包或检查 plugin_dir 权限
改完还连不上?这些细节比插件切换更常导致失败
很多问题其实和认证插件无关,但容易被忽略:
- Navicat / DBeaver 会缓存握手参数,改完服务端后必须彻底关闭软件、删除旧连接、重建新连接
- PHP-FPM 或 Java 应用连接池没重启,旧连接仍复用失败握手逻辑,得重启对应进程
- 密码含 @、/、! 等字符时,命令行连接要加单引号:mysql -uroot -p'pass!@#',否则 shell 解析出错
- phpinfo() 显示 Client API version 是 5.7.x,说明 PHP 调用的还是旧版 libmysqlclient,此时即使服务端切了插件,客户端也可能因底层库不支持而静默失败


















