Ubuntu 26.04 upgrade stops with "Unable to upgrade MySQL" (mysql_native_password accounts)
Unable to upgrade MySQL
The following MySQL accounts use the mysql_native_password authentication plugin, which is disabled by default in the version of MySQL shipped with this release:
mysql.session@localhost
mysql.sys@localhost
These accounts would be locked out after the upgrade.
Short answer: Ubuntu's release upgrader stops the 24.04 to 26.04 upgrade if any MySQL account still uses mysql_native_password, because 26.04 ships MySQL 8.4, where that plugin is off by default. If the list shows only mysql.sys and mysql.session, they are MySQL's own locked system accounts: convert them with the statement MySQL itself uses and run the upgrade again. If your own app accounts are listed, convert them, or add loose-mysql_native_password=ON to mysqld.cnf. Don't add the plain mysql_native_password=ON from the release notes on 24.04: its MySQL 8.0 refuses to start with it.
Why it happens
Before upgrading to 26.04, the upgrader (DistUpgradeQuirks.py) runs my_print_defaults mysqld. If that shows mysql_native_password=ON (with or without a loose- prefix), it lets the upgrade continue. Otherwise it lists every account whose plugin is mysql_native_password and stops. The 26.04 release notes say to add mysql_native_password=ON, but that option only exists in MySQL 8.4. MySQL 8.0, which 24.04 still runs, does not know it: in our test the official 8.0.46 build stopped with "unknown variable 'mysql_native_password=ON'" and "Aborting". With the loose- prefix, MySQL 8.0 only logs a warning and keeps running (the MySQL manual documents this for option files). my_print_defaults then prints --loose-mysql_native_password=ON, which the upgrader's check accepts, and MySQL 8.4 turns the plugin on after the upgrade. mysql.sys and mysql.session are on the list on servers that started on MySQL 5.7: 5.7 created them with mysql_native_password, and the 5.7 to 8.0 upgrade left them that way. They are locked and never log in, and MySQL 8.4's own upgrade step converts them to caching_sha2_password anyway (mysql_system_tables_fix.sql). So for these two the warning is a false alarm, but it still blocks the upgrade. Tested on 28 October 2026 with Oracle's official MySQL 8.0.46 and 8.4.8 builds (the versions in Ubuntu 24.04 and 26.04) on a data directory set up like a 5.7-era server, and with the upgrader's own check code.
You may also see
[ERROR] [MY-000067] [Server] unknown variable 'mysql_native_password=ON'.ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded
Fix
- Take a backup first (mysqldump or a VM snapshot). Then list the accounts the upgrader sees. This is the same query it runs:
The upgrade dialog shows at most three accounts and then "...", so this query is the full list.sudo mysql -e "SELECT CONCAT(User,'@',Host) FROM mysql.user WHERE plugin='mysql_native_password';" - If the list shows only mysql.sys@localhost and mysql.session@localhost, give them the locked-account entry MySQL uses for these accounts on new installs. They stay locked, nothing can log in with them, and the sys schema keeps working (all three checked in our test):
Run the step 1 query again: it should print nothing. Then start the release upgrade again (sudo mysql <<'SQL' ALTER USER 'mysql.sys'@'localhost' IDENTIFIED WITH caching_sha2_password AS '$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED'; ALTER USER 'mysql.session'@'localhost' IDENTIFIED WITH caching_sha2_password AS '$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED'; SQLsudo do-release-upgrade). - If your own accounts are listed (for example an app user), choose one of these. (a) Convert each one with
ALTER USER 'user'@'host' IDENTIFIED WITH caching_sha2_password BY 'its-current-password';, taking the password from the app's config. Before you do, check that the app's MySQL driver supports caching_sha2_password. (b) Keep them as they are for now: add one line to mysqld.cnf, restart, and check that the upgrader will see it:
MySQL 8.0 logs "[Warning] unknown variable 'loose-mysql_native_password=ON'" and keeps running. Then run the release upgrade again.# /etc/mysql/mysql.conf.d/mysqld.cnf, in the [mysqld] section loose-mysql_native_password=ON sudo systemctl restart mysql sudo my_print_defaults mysqld | grep native_password # --loose-mysql_native_password=ON <- the line the upgrade check looks for - After the upgrade, if you used option (b), check that the plugin is on and that your apps connect:
Move those accounts to caching_sha2_password over time and then remove the line. A later Ubuntu release that ships MySQL 9.7 has the opposite check: the upgrader refuses to continue while the option is still set.sudo mysql -e "SELECT PLUGIN_STATUS FROM information_schema.PLUGINS WHERE PLUGIN_NAME='mysql_native_password';" # ACTIVE
Watch out
- Don't use the plain mysql_native_password=ON on 24.04. The upgrade check accepts it, but MySQL 8.0 won't start with it, so any restart before the upgrade is an outage.
- Write the value as ON. The upgrade check only accepts ON, FORCE or FORCE_PLUS_PERMANENT, so =1 or =TRUE still blocks the upgrade (tested with the check's own code).
- The check only runs while MySQL is running. If MySQL is stopped, the upgrade goes ahead, and afterwards app accounts on mysql_native_password fail with "ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded" (we got exactly this on MySQL 8.4.8 with no fix applied).
- Ubuntu's own accounts (root and debian-sys-maint use auth_socket) are not affected.
Sources
- Ubuntu release upgrader: the MySQL check in DistUpgradeQuirks.py
- Ubuntu 26.04 LTS release notes: MySQL
- MySQL 8.4 manual: Native Pluggable Authentication
- MySQL 8.0 manual: Program Option Modifiers (loose)
- MySQL 8.4 source: scripts/mysql_system_tables_fix.sql (converts mysql.sys and mysql.session)
- MySQL 8.0 source: scripts/mysql_system_users.sql (how MySQL creates its locked system accounts)
Other errors breaking soon
- Firebase: Runtime Node.js 20 was decommissioned
- Google Cloud Python: non-supported Python version (3.10)
- OpenAI: "The model … has been deprecated" or "Model not found" after a shutdown
- pytest 9.2: xdist_group tests run on different workers (--dist loadgroup)
- WordPress 7.2 ignores data-wp-init--, data-wp-watch-- and data-wp-run-- directives