Troubleshooting

Fix MySQL or MariaDB error 1045: Access denied for user

Error 1045 means MySQL or MariaDB rejected the login. Find which user and host the client asked for, fix the password or grants, and reset a lost root password safely.

IntermediateLinux server6 min read

Error 1045 means the server understood your login attempt and refused it. The fix is almost never the server itself — it is a mismatch between the user, the host part, the password or the grants the server has on record. This guide walks through each one in the order that finds the problem fastest, then shows how to recover when root is locked out.

Before you start

You need:

  • SSH access to the VPS as a user who can run sudo — see Connect to your Linux VPS with SSH if you have not done that yet.
  • The exact error text. Copy it whole; the part after @ and the using password flag matter.
  • Root or sudo access to the database server, because the fixes happen inside MySQL.

Check which engine you are running, since the commands are nearly identical but the service names differ:

Bash
mysql --version
systemctl status mysql mariadb --no-pager

On Ubuntu and Debian the service is usually mariadb or mysql. On AlmaLinux and Rocky it is mysqld.

Note: A full error line looks like ERROR 1045 (28000): Access denied for user 'deploy'@'localhost' (using password: YES). Write down the user, the host after @, and whether it says YES or NO.

Read the error line

Three pieces of that message tell you where to look:

  • The user name — was it deploy, root, or something your app config invented?
  • The host part — localhost, 127.0.0.1, or a remote IP. On Linux, localhost means a Unix socket, while 127.0.0.1 means TCP. These are different accounts to MySQL.
  • using password: YES or NO — NO means the client sent no password at all, so the problem is configuration, not a wrong password.

If your app reports 1045 but the CLI works fine, the app is connecting to a different host string than you are. Check the app's config file before touching the database.

Check the user and host entry

Log in as the database administrator. On a fresh Ubuntu or Debian install, root uses socket authentication, so this works without a password:

Bash
sudo mysql

On MariaDB the equivalent is sudo mariadb. Then list the accounts:

SQL
SELECT user, host, plugin FROM mysql.user WHERE user = 'deploy';

What you want to see is an exact match for how the client connects. If your app uses 127.0.0.1, a row for 'deploy'@'localhost' will not help. 'deploy'@'%' matches any host, 'deploy'@'127.0.0.1' matches only TCP loopback.

Create the missing entry:

SQL
CREATE USER 'deploy'@'127.0.0.1' IDENTIFIED BY 'StrongPassw0rd!';

Then set the password on the exact row you need, which is the cleanest way to rule out a stale credential:

SQL
ALTER USER 'deploy'@'127.0.0.1' IDENTIFIED BY 'StrongPassw0rd!';
FLUSH PRIVILEGES;

If the plugin column shows unix_socket, that account only accepts logins from a matching Linux user over the socket — a password will never work. Change it with ALTER USER... IDENTIFIED VIA mysql_native_password USING PASSWORD('...') on MariaDB, or recreate the user on MySQL. Check your engine's documentation, because the authentication plugin defaults have changed between major versions.

Check the grants

A user can exist with a valid password and still be refused if it has no privileges on the target database. That normally returns error 1044, but misconfigured stacks often surface both. Inspect what the account actually holds:

SQL
SHOW GRANTS FOR 'deploy'@'127.0.0.1';

If the output is only GRANT USAGE ON *.*, the account has no real rights. Grant what the application needs and no more:

SQL
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'deploy'@'127.0.0.1';
FLUSH PRIVILEGES;

For a full setup walkthrough including remote access, see How to create a MySQL user and grant privileges and Install and secure MariaDB or MySQL.

Reset a lost root password

If you cannot get in at all — including as root — start the server with authentication disabled, change the password, and restart it normally.

Warning: This restarts the database and briefly allows passwordless local logins. Any application using the database will drop its connections. Do this in a quiet window, and keep --skip-networking so nothing can reach it from the network.

Bash
sudo systemctl stop mysql
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mysql

Connect and set a new password. Notice the FLUSH PRIVILEGES first — it is required, because with grant tables skipped the account rows are not loaded:

SQL
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongRootPassword!';

On older MySQL 5.7-style servers use SET PASSWORD FOR 'root'@'localhost' = PASSWORD('NewStrongRootPassword!'); instead. Then stop the server, clear the override, and start it again:

Bash
sudo systemctl stop mysql
sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl start mysql

On MariaDB, swap mysql for mariadb in every command above. On AlmaLinux and Rocky, the service unit is mysqld.

Check it works

Log in with the password rather than the socket shortcut, which proves the credential itself works:

Bash
mysql -u deploy -p -h 127.0.0.1 appdb

Enter the password when asked. Then confirm you are in the right place and the account sees its data:

SQL
SELECT CURRENT_USER(), DATABASE();
SHOW TABLES;

CURRENT_USER returns the account MySQL matched, including the host part — that is the row you were fighting with. Restart the application and recheck its logs; a cached connection pool may need a reload.

Troubleshooting

  • Still 1045 after ALTER USER → you changed a different host row. Run SELECT user, host FROM mysql.user WHERE user = 'deploy'; and change the row whose host matches the client's connection method exactly.
  • CLI works, application does not → the app config still holds the old password, or it connects to localhost (socket) while you created 127.0.0.1 (TCP). Align both, and quote passwords containing #, ; or spaces in .ini and .env files.
  • using password: NO → the client sent no password. Check for an empty password field, a missing MYSQL_PWD, or a --defaults-file that points at the wrong config. See Where is my.cnf?.
  • sudo mysql works but mysql -u root -p fails → that is socket authentication, not a bug. Set a password explicitly as shown above if you need password logins for root.
  • 1044 instead of 1045 → the login succeeded but the account lacks rights on that specific database. Grant privileges on the database named in the message.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.