“MySQL ERROR 1045 access denied for user” is one of the most common errors encountered when connecting to MySQL or MariaDB. It appears at the command line, in application logs, and inside WordPress wp-config.php connection failures when the server rejects the client’s authentication request.

This article covers the most common causes of ERROR 1045 and walks through the exact commands to fix each one on Linux servers running MySQL 5.7, MySQL 8.0, and MariaDB.
Table of Contents
What Is MySQL ERROR 1045?
The full error message takes this form:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
or
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
MySQL rejected the connection because the combination of username, host, and password did not match any authorized entry in the mysql.user table. The (using password: YES/NO) part tells you whether a password was supplied at all — useful for narrowing down the cause immediately.
Common Causes
- Incorrect password or username
- Root password was never set after installation
- The user account does not exist in
mysql.user - The user exists but is not allowed to connect from the current host
- MySQL 8.0 changed the default authentication plugin, breaking older clients
skip-grant-tableswas previously used and privileges were not re-flushed
Fix 1: Wrong Password
The most frequent cause. Verify you are using the correct credentials before anything else.
1.1 — Attempt login with explicit host:
mysql -u root -p -h 127.0.0.1
Using -h 127.0.0.1 instead of -h localhost forces a TCP connection rather than a Unix socket. If this succeeds while localhost fails, the issue is socket-based authentication, not the password itself.
1.2 — Check if the user exists:
Log in as a privileged user (or use the root recovery method below) and run:
SELECT user, host, authentication_string FROM mysql.user WHERE user = 'your_username';
If no row is returned, the user does not exist — create it (see Fix 3).
1.3 — Verify credentials in your application config:
For WordPress, open wp-config.php and confirm these values are accurate:
define('DB_USER', 'your_db_user');
define('DB_PASSWORD', 'your_db_password');
define('DB_NAME', 'your_db_name');
define('DB_HOST', 'localhost');
Fix 2: Reset a Lost Root Password
If you cannot log in to MySQL at all, use the --skip-grant-tables method to bypass authentication temporarily.
Warning:
skip-grant-tablesdisables authentication for all users while active. Only use this on a server you control and revert it immediately.
Step 1 — Stop the MySQL service:
# systemd (Ubuntu 16.04+, CentOS 7+)
sudo systemctl stop mysql
# For MariaDB
sudo systemctl stop mariadb
Step 2 — Start MySQL with grant tables disabled:
sudo mysqld_safe --skip-grant-tables --skip-networking &
--skip-networking prevents remote connections while the server is unprotected.
Step 3 — Connect without a password:
mysql -u root
Step 4 — Flush privileges and reset the password:
For MySQL 5.7:
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword!';
For MySQL 8.0 and MariaDB 10.4+:
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'NewStrongPassword!';
FLUSH PRIVILEGES;
Step 5 — Stop the temporary instance and restart MySQL normally:
sudo kill $(sudo cat /var/run/mysqld/mysqld.pid)
sudo systemctl start mysql
Step 6 — Test the new password:
mysql -u root -p
Fix 3: Missing or Incorrect User Privileges
If the user account is missing entirely, or it exists but lacks the necessary privileges, MySQL returns ERROR 1045.
3.1 — Create a new user and grant privileges:
CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'StrongPassword!';
GRANT ALL PRIVILEGES ON your_database.* TO 'dbuser'@'localhost';
FLUSH PRIVILEGES;
To grant access from any host (use with caution on public-facing servers):
CREATE USER 'dbuser'@'%' IDENTIFIED BY 'StrongPassword!';
GRANT ALL PRIVILEGES ON your_database.* TO 'dbuser'@'%';
FLUSH PRIVILEGES;
3.2 — Check current privileges for a user:
SHOW GRANTS FOR 'dbuser'@'localhost';
3.3 — Grant missing privileges to an existing user:
GRANT SELECT, INSERT, UPDATE, DELETE ON your_database.* TO 'dbuser'@'localhost';
FLUSH PRIVILEGES;
Fix 4: Host Mismatch
MySQL stores user accounts as 'username'@'host' pairs. A user created for localhost cannot connect from 127.0.0.1 or a remote IP unless a separate account exists for that host.
4.1 — Check which hosts are defined for a user:
SELECT user, host FROM mysql.user WHERE user = 'dbuser';
Example output showing a host mismatch:
+--------+-----------+
| user | host |
+--------+-----------+
| dbuser | localhost |
+--------+-----------+
If your application connects from 192.168.1.50 or via 127.0.0.1, this account will not match.
4.2 — Add the correct host:
CREATE USER 'dbuser'@'192.168.1.50' IDENTIFIED BY 'StrongPassword!';
GRANT ALL PRIVILEGES ON your_database.* TO 'dbuser'@'192.168.1.50';
FLUSH PRIVILEGES;
Or use a wildcard for a subnet:
CREATE USER 'dbuser'@'192.168.1.%' IDENTIFIED BY 'StrongPassword!';
GRANT ALL PRIVILEGES ON your_database.* TO 'dbuser'@'192.168.1.%';
FLUSH PRIVILEGES;
4.3 — Verify the connecting IP:
# From the client machine
curl -s https://api.ipify.org
Or on the server, check recent connection attempts:
sudo grep "Access denied" /var/log/mysql/error.log | tail -20
Fix 5: Authentication Plugin Mismatch (MySQL 8.0+)
MySQL 8.0 changed the default authentication plugin from mysql_native_password to caching_sha2_password. Many older clients, PHP versions, and applications do not support the new plugin, resulting in ERROR 1045 or a related Client does not support authentication protocol error.
5.1 — Check the current plugin for a user:
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
5.2 — Switch to mysql_native_password for compatibility:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourPassword';
FLUSH PRIVILEGES;
5.3 — Set it as the global default (optional):
Add the following to /etc/mysql/mysql.conf.d/mysqld.cnf (or /etc/my.cnf):
[mysqld]
default_authentication_plugin=mysql_native_password
Then restart MySQL:
sudo systemctl restart mysql
Prevention Tips
Use separate database users per application. Never connect your web applications using the root account. Create a dedicated user with the minimum privileges required for each application.
Run FLUSH PRIVILEGES after manual user table edits. If you ever edit the mysql.user table directly with UPDATE instead of using ALTER USER or GRANT, MySQL will not read the changes until you run:
FLUSH PRIVILEGES;
Restrict remote access. Only allow remote MySQL connections from specific IP addresses. In /etc/mysql/mysql.conf.d/mysqld.cnf, set:
bind-address = 127.0.0.1
This limits MySQL to listen on localhost only, unless you explicitly need remote access.
Keep authentication plugins consistent. When upgrading MySQL from 5.7 to 8.0, audit user authentication plugins beforehand to avoid breaking existing connections.
Log failed access attempts. Enable the general query log temporarily when troubleshooting to see what credentials are being used:
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/general.log';
Disable it after troubleshooting — it is not suitable for production use under load.
Conclusion
MySQL ERROR 1045 always comes down to one of five issues: a wrong password, a missing user account, a privilege gap, a host mismatch, or an authentication plugin conflict in MySQL 8.0. Work through the fixes in order — most cases are resolved by Fix 1 or Fix 3 without needing the skip-grant-tables recovery procedure.