MySQL 1045: Access Denied for 'root'@'localhost'
You're locked out of MySQL with error 1045. The fix is resetting the root password via skip-grant-tables. Here's the exact steps.
You're staring at Access Denied. It happens.
MySQL error 1045 (28000) — Access denied for user 'root'@'localhost' (using password: YES/NO) — usually hits after a fresh install, a password change that didn't stick, or an upgrade that broke your authentication plugin. The core problem: MySQL won't accept the password you're sending. The fix is to bypass authentication entirely, reset the root password, then lock it back down.
Step 1: Stop MySQL and restart with auth bypass
First, stop the MySQL service. On Ubuntu/Debian:
sudo systemctl stop mysql
On macOS (Homebrew):
brew services stop mysql
On Windows (run Command Prompt as Admin):
net stop MySQL80
Now start MySQL with --skip-grant-tables. This tells MySQL to load the database engine but skip the privilege checks entirely.
Linux/macOS:
sudo mysqld_safe --skip-grant-tables &
If that command hangs or doesn't exist, try:
sudo mysqld --skip-grant-tables --user=mysql &
Windows:
mysqld --skip-grant-tables --console
Keep that terminal window open.
Step 2: Connect without a password and flush privileges
In a second terminal (or new Command Prompt), connect without a password:
mysql -u root
If that fails, try:
mysql -u root -p
and press Enter when asked for a password. Once you're in, run:
FLUSH PRIVILEGES;
The FLUSH PRIVILEGES forces MySQL to reload the grant tables into memory. Without this step, your ALTER USER command in the next step might silently do nothing.
Step 3: Set a new root password
Now set a new password. For MySQL 5.7+ and 8.0+:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewStrongPassword';
If your MySQL version is older (5.6 or earlier), or the above fails because of your authentication plugin, use:
UPDATE mysql.user SET authentication_string=PASSWORD('YourNewStrongPassword') WHERE User='root' AND Host='localhost';
Then FLUSH PRIVILEGES; again, just to be safe.
Step 4: Restart MySQL normally
Exit the MySQL prompt with exit;. Stop the MySQL process you launched with --skip-grant-tables. On Linux, kill the process if needed:
sudo killall mysqld
Then start MySQL normally:
sudo systemctl start mysql
Test the new password:
mysql -u root -p
Enter the password you set. You should be in.
Why this worked
The --skip-grant-tables flag is effectively a backdoor key. It tells MySQL to ignore its authentication system entirely — no password checks, no privilege lookups. You're running the server in a degraded trust mode. That's why you must restart MySQL normally after the fix. Leaving it running with --skip-grant-tables exposed to a network is a security disaster waiting to happen.
The reason step 3 works with ALTER USER but not always with the old UPDATE is that MySQL 8.0 changed the authentication plugin default from mysql_native_password to caching_sha2_password. The ALTER USER command handles both. The UPDATE method only works if the old plugin is already in place.
Less common variations of the same error
Error 1045 with 'root'@'127.0.0.1' instead of 'localhost'
If the error says 'root'@'127.0.0.1', you're connecting via TCP even when on the same machine. This happens when you use mysql -u root -h 127.0.0.1 instead of mysql -u root -h localhost. Localhost connections use a Unix socket (Linux/macOS) or named pipe (Windows). TCP connections go through the network stack and hit a different user entry in the mysql.user table. To fix this, either connect via localhost or set a password for root@127.0.0.1 separately:
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY 'YourNewStrongPassword';
Error 1045 after MySQL 8.0 upgrade
If you upgraded from MySQL 5.7 to 8.0, the old password hash format won't work. MySQL 8.0 rejects mysql_native_password hashes from 5.7. The symptom: you can connect locally via the socket but not via TCP. The fix is to upgrade the authentication plugin:
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'YourNewStrongPassword';
Error 1045 when password is correct but plugin is wrong
Rare but real: the password is right, but the authentication_string field is empty while the plugin column demands a non-empty hash. Check the user table:
SELECT user, host, plugin, authentication_string FROM mysql.user WHERE user='root';
If plugin is caching_sha2_password but authentication_string is blank, you need to set the password (which writes the hash). The ALTER USER command above does exactly that.
How to prevent this from happening again
- Use a password manager — store the root password in a secure vault. Don't rely on memory.
- Create a secondary admin user — set up a non-root user with full privileges. If you lock out root, you can fix it with that user.
- Test password changes immediately — after changing the root password, open a new terminal and verify you can connect. Don't close the first session until you confirm.
- Know your authentication plugin — if you're on MySQL 8.0, understand that
caching_sha2_passwordis the default. Some older clients (like PHP'smysql_connector oldlibmysqlclient) don't support it. You may need to explicitly setmysql_native_passwordfor those clients:
ALTER USER 'myapp'@'localhost' IDENTIFIED WITH mysql_native_password BY 'app_password';
- Backup your grant tables — export them periodically:
mysqldump mysql user db tables_priv columns_priv procs_priv proxies_priv --where="1=1" > grants_backup.sql
This dump can save you if the user table gets corrupted.
That's the whole thing. No fluff, no hand-holding. You should be back in.
Was this solution helpful?