MySQL Error 1146

MySQL 8.0 Startup Fail: Table 'mysql.plugin' Missing? Fix It

After upgrading to MySQL 8.0, the server won't start because the data dictionary is out of sync. Here's how to fix it fast.

Cause #1: You Skipped mysql_upgrade or Ran the Wrong Version

The most common reason for this error is that you upgraded your MySQL binaries but never ran mysql_upgrade (or ran an old version of it). MySQL 8.0 introduced a new data dictionary, and the system tables like mysql.plugin are now stored differently. If you jump from 5.7 to 8.0 without letting MySQL rebuild those tables, the server refuses to start and throws Error 1146.

Here's the thing: in MySQL 8.0, mysql_upgrade is actually deprecated—you don't need to run it manually if you let the server initialize properly. But if you upgraded in-place (e.g., using rpm -U or apt upgrade) and the post-install scripts didn't trigger, you're stuck.

The Fix

  1. Stop the MySQL service if it's running (it probably isn't).
  2. Back up your data directory. Just in case. cp -a /var/lib/mysql /var/lib/mysql_backup
  3. Start MySQL with the --skip-grant-tables option to bypass the missing table check:
mysqld --skip-grant-tables --user=mysql &

This lets the server start without trying to load the plugin table. Then run:

mysql_upgrade -u root -p

If you get an error about mysql_upgrade not being found, you're using a 5.7 client—make sure your PATH points to the 8.0 installation (/usr/local/mysql/bin or similar).

After it finishes (it'll take a while), stop the server and start it normally:

mysqladmin shutdown
systemctl start mysql

That usually fixes it. If not, move on to cause #2.

Cause #2: Incompatible Data Dictionary After a Failed Upgrade

Sometimes the upgrade partially completes, leaving the data dictionary in a weird state. You might see errors like Table 'mysql.plugin' doesn't exist but also other corruption messages. This happens when the upgrade process crashes mid-way, or when you copy data files from a 5.7 install into an 8.0 data directory.

The mysql.plugin table is one of the first system tables MySQL checks on startup. If the dictionary says it should exist but the actual .ibd file is missing or corrupt, the server bails.

The Fix

I don't like this fix, but it works: force InnoDB recovery to let the server start, then rebuild the table.

  1. Add this to your my.cnf under [mysqld]:
innodb_force_recovery=1

Start MySQL. If it starts, great. Now run mysql_upgrade again. But here's the catch—with innodb_force_recovery set to anything above 0, you can't write to InnoDB tables. So you'll need to:

  1. Stop the server, remove the innodb_force_recovery line, and restart.
  2. If it still won't start, bump the recovery level up to 6 (the max). This disables most background operations, but it often lets the server start long enough to export data.

If you manage to get in, dump everything with mysqldump and reimport into a fresh 8.0 install. That's the nuclear option, but it's the only way to be sure your data dictionary is clean.

Cause #3: Permissions or Ownership Issues on the Data Directory

This one's sneaky. If the mysql user doesn't have read/write access to the data directory (or the mysql.plugin.ibd file specifically), MySQL can't open the table. You'd think the error would be about permissions, but it often surfaces as Table 'mysql.plugin' doesn't exist because the server can't even see the file.

I saw this happen on a CentOS 7 server after a partial restore from a backup—the file permissions got messed up.

The Fix

  • Check ownership: ls -la /var/lib/mysql/mysql/plugin.*. They should be owned by mysql:mysql.
  • Fix it: chown -R mysql:mysql /var/lib/mysql
  • While you're at it, verify the file exists: ls -la /var/lib/mysql/mysql/plugin.ibd. If it's missing, you might have to restore it from a backup or reinitialize.

If the file is truly gone, and you don't have a backup, you can create a fresh MySQL data directory by moving the old one aside and initializing a new one:

mv /var/lib/mysql /var/lib/mysql_old
mkdir /var/lib/mysql
chown mysql:mysql /var/lib/mysql
mysqld --initialize-insecure --user=mysql

That gives you a clean install, but you'll lose all databases unless you have a dump. That's a hard lesson, but it's better than being stuck in a boot loop.

Quick Reference Table

CauseSymptomFix
Missing mysql_upgradeError right after upgrade, before any other issuesRun mysql_upgrade (or restart with --skip-grant-tables first)
Corrupt data dictionaryError plus other corruption messages, partial upgradeUse innodb_force_recovery to start, dump, reimport
Permissions/ownershipError after restore or file move, file missingchown -R mysql:mysql /var/lib/mysql, or reinitialize

One last tip: before you upgrade, always mysqldump your databases. I've said this a hundred times, but it's the only way to make these problems a minor annoyance instead of a disaster.

Related Errors in Database Errors
0X00000202 STATUS_RESOURCEMANAGER_READ_ONLY 0X00000202 Fix WriteConcernTimeout MongoDB Write Concern Timeout Exceeded – Fix It Fast ERROR 1040 (HY000): Too many connections MySQL Error 1040: Too Many Connections — Real Fix 18456 SQL Server 'Login failed for user' Error Fix

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.