Yeah, error 1045 is annoying as hell. You're staring at your terminal, sure you typed the password right, and MySQL still tells you to get lost. Let's cut the crap and fix it now.
The Usual Fix
In 8 out of 10 cases, the culprit is almost always a typo in the password or the username. But you've already checked that, right? So let's assume you're getting this:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
That means MySQL got your request, looked up the user, and said nope. Here's the fastest way to break back in if you've lost or forgotten the root password — or if someone else changed it and didn't tell you.
- Stop the MySQL service. On Ubuntu, that's
sudo systemctl stop mysql. On CentOS it'ssudo systemctl stop mysqld. If you're on Windows, usenet stop mysql(run as admin). - Start MySQL in safe mode, skipping all privilege checks.
sudo mysqld_safe --skip-grant-tables & - Now connect without a password:
mysql -u root - Run these commands one by one:
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewStrongPassword';
FLUSH PRIVILEGES;
EXIT;
Then restart MySQL normally. sudo systemctl restart mysql. Done.
Why This Works
--skip-grant-tables tells MySQL to completely ignore its user tables. No authentication, no rules, just open the door. That's why the first FLUSH PRIVILEGES is critical — it tells the server to reload the privilege tables from disk, otherwise the ALTER USER might not take effect properly. It's a classic gotcha that trips up people who think they've reset the password but haven't.
Less Common Variations
Sometimes the problem isn't the password. Here are the sneaky ones I've seen in production.
1. Wrong Host in the Error
If you see 'user'@'192.168.1.50' instead of 'user'@'localhost', that's a host mismatch. MySQL doesn't automatically create a user for every IP. You need to explicitly allow that host. As root, do:
CREATE USER 'appuser'@'192.168.1.50' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'192.168.1.50';
FLUSH PRIVILEGES;
Or if you want to allow any host (not great for security, but common on dev boxes):
CREATE USER 'appuser'@'%' IDENTIFIED BY 'password';
2. Empty Password with using password: NO
If the error says using password: NO, but you're sure you passed one, check your client config. MySQL reads ~/.my.cnf and sometimes has a password that overrides what you type. Or the opposite — it has an empty password and you're trying to type one. Look for an my.cnf file and comment out any password line.
3. MySQL 8 with caching_sha2_password
MySQL 8 changed the default authentication plugin. Older clients (PHP 7.1 and below, some Python libs) can't handle it, so they throw 1045 even with the right password. The quick workaround is to switch that user back to the old plugin:
ALTER USER 'appuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
That's saved me more than once when dealing with legacy apps.
Prevention
Do these three things and you'll rarely see 1045 again.
- Use a single source of truth for credentials. Put them in a config file that your app reads — don't hardcode them in 14 different scripts. When you change a password, you change it in one place.
- Track your MySQL changes. Keep a simple changelog or use a migration tool like Flyway. I can't tell you how many times 1045 was caused by an undocumented password change from a coworker who 'just fixed it quickly'.
- Set strong but memorable passwords. If you're constantly resetting, you'll end up doing the skip-grant-tables dance too often. And that's a security risk in itself.
One more thing — if you use a password manager, great. If not, at least write it down in a secure note. Future you will appreciate it.