MySQL ERROR 1045 "Access Denied for User 'root'@'localhost'": Every Fix on Amazon Linux 2023, Docker and RDS

Logeshwaran
—

ERROR 1045 (28000): Access denied for user 'root'@'localhost' means MySQL found an account that could match you, but the user name and password didn't. The ending tells you which half to fix: (using password: NO) means no password was sent at all, and (using password: YES) means one was sent and it was wrong. Use the one that works for your setup, or reset it: on RDS with one command, and on your own server with --skip-grant-tables. But check three traps first, because they cause most of these errors and none of them is a forgotten password. On Amazon Linux 2023, MariaDB's root has no password at all; you sign in with sudo mysql, and following a MySQL tutorial's ALTER USER root ... IDENTIFIED BY there locks sudo mysql out. In Docker, changing MYSQL_ROOT_PASSWORD doesn't change the password of a database that already exists. And a forgotten ~/.my.cnf can send an old password without you typing one. This page shows each case with its exact message, and the fix that matches.

Ethan, a developer, runs the booking app for his friend Jake's phone repair shop on an EC2 server with MariaDB. A security checklist told him to "set a root password", so he ran the command from a MySQL tutorial. The next morning, sudo mysql, which had worked for months, said ERROR 1045.

⚡ Quick Answer

• MariaDB on Amazon Linux 2023: use sudo mysql; root has no password. Why.

• Forgot the root password: restart with --skip-grant-tables, run FLUSH PRIVILEGES, then ALTER USER. Steps.

• Docker: the password is the one from the first start. The volume trap.

• RDS: aws rds modify-db-instance --master-user-password. Reset it.

If the message says "is not allowed to connect" instead, that's ERROR 1130, a host problem, not a password one.

New to these terms? MariaDB is the MySQL-compatible database that Amazon Linux 2023 installs; its mysql command and error messages work the same way. Docker runs MySQL in a container, with its data kept in a volume.

🧭 NEW HERE? READ THESE FIRST

New to EC2, RDS and Docker? These five pages make the rest of this one easy:

📌 Bookmark this; the decoder table is the part you will come back for.

Read the message: three versions, three meanings

These three lines look nearly the same, and each one needs a different fix:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
ERROR 1045 (28000): Access denied for user 'app'@'localhost' (using password: YES)
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
MessageWhat it meansFix
1045 ... (using password: NO)No password was sent, and this account needs oneAdd -p, or, for a lost one, reset it
1045 ... (using password: YES)A password was sent and it didn't matchCheck the password, the shell, ~/.my.cnf and anonymous accounts
1698 for root, no "using password"The account signs in by system identity, not by password (MariaDB)Use sudo mysql
1130 "is not allowed to connect"No account exists for the host you came fromCreate the account for that host

One thing that's always true: the 'localhost' part is where MySQL thinks you came from, not where the account was created. An account made for '%' still shows up as 'app'@'localhost' in the message when you connect on the same machine.

"using password: YES" when you didn't type one

If the message says YES but you never typed a password, something sent one for you. The usual suspect is an old ~/.my.cnf file, which the client reads every time it starts. You can see what it'll use:

mysql --print-defaults
mysql would have been started with the following arguments:
--user=app --password=Old-pass-000

That stored password was changed months ago, so every connection fails with (using password: YES), even mysql -u app with no -p. Update the file, or delete the password line and type it with -p. The MYSQL_PWD environment variable, if it's set, does the same thing, so check echo $MYSQL_PWD too.

The other way a correct password arrives wrong is the shell itself. A password with $ in it, typed straight after -p, is changed by the shell before MySQL sees it:

mysql -u pay -pPa$$word-9 -e "SELECT 1"
ERROR 1045 (28000): Access denied for user 'pay'@'localhost' (using password: YES)

The shell replaced $$ with a number, its own process ID. Wrap the password in single quotes, -p'Pa$$word-9', or type just -p and enter it at the prompt, where the shell can't touch it.

MariaDB on Amazon Linux 2023: root has no password

Here's the first surprise. On a new MariaDB server on Amazon Linux 2023, root doesn't have a password you've forgotten; it has none at all:

sudo mysql -N -e "SHOW CREATE USER root@localhost"
CREATE USER `root`@`localhost` IDENTIFIED VIA mysql_native_password USING 'invalid' OR unix_socket

Read it from the end: unix_socket means "let in whoever is the Linux user root", and the password half is set to 'invalid', which no password can match. So sudo mysql works, and anything else is refused, with ERROR 1698 rather than 1045, password or not:

mysql -u root -p
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

That's a safe default, not a fault: nobody can guess a password that doesn't exist. For your app, and for tools that need a password, create a separate account instead of changing root.

Jake: "So root's password was never lost. There wasn't one?"

Ethan: "There wasn't one. The server trusted my sudo. Then I gave it a password and it stopped trusting my sudo."

The trap: a MySQL tutorial that locks sudo mysql out

Here's what Ethan ran, straight from a MySQL guide:

sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root-pass-1';"
sudo mysql -e "SELECT 1"
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

On MariaDB, IDENTIFIED BY replaces how root signs in. The unix_socket part is gone, so sudo no longer counts, and root now needs the password, which sudo mysql doesn't send. If you know the password you set, sign in with it and put both methods back, so sudo mysql works again and the password works too:

sudo mysql -u root -p'Root-pass-1' -e "ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('Root-pass-1');"
sudo mysql -N -e "SELECT CURRENT_USER()"
root@localhost

If you don't know it any more, the reset below works the same.

Reset a forgotten root password on your own server

To reset root, you restart the server in a mode that skips all password checks, set the password, and restart it normally. On Amazon Linux 2023, MariaDB's service reads extra options from MYSQLD_OPTS, so you don't edit any files:

  1. Stop the server, and start it without password checks and without network access, so nobody else can get in while it's open.
  2. Run FLUSH PRIVILEGES first; it reloads the account tables, and without it every ALTER USER fails with ERROR 1290.
  3. Set root back to how you want it: socket only, as below, or socket plus a password.
  4. Remove the extra options and restart normally.
sudo systemctl stop mariadb
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mariadb
sudo mysql -e "FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket;"
sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl restart mariadb
sudo mysql -N -e "SELECT CURRENT_USER()"
root@localhost

Skip step 2's FLUSH PRIVILEGES, and the client repeats your statement back, then stops with this error:

ERROR 1290 (HY000) at line 1: The MariaDB server is running with the --skip-grant-tables option so it cannot execute this statement

Don't leave out --skip-networking on MariaDB. Without it, the server keeps accepting network connections while password checks are off, so anyone who can reach port 3306 gets in as anyone. MySQL 8.4 turns networking off by itself in this mode; MariaDB 10.11 doesn't:

MariaDB 10.11 (Amazon Linux 2023)MySQL 8.4 (Docker image)
How root signs in by defaultsudo mysql, by system identityPassword from MYSQL_ROOT_PASSWORD
Wrong root login givesERROR 1698ERROR 1045
Network off with --skip-grant-tablesNo: add --skip-networkingYes, automatically
FLUSH PRIVILEGES before ALTER USERNeededNeeded

Jake: "Isn't that a back door?"

Ethan: "Only for someone who can already run sudo on the server. If they can do that, the database is the least of your worries."

MySQL in Docker: the password from the first start wins

The official MySQL image sets root's password from MYSQL_ROOT_PASSWORD, and leaving out -p gives the plain version of the error:

docker exec -it shop-mysql mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

Here's the second surprise. The image only uses MYSQL_ROOT_PASSWORD when it creates the database, on the very first start with an empty volume. Change the value in your docker-compose.yml later, recreate the container, and the new password fails with (using password: YES) while the old one still works, because the database in the volume kept it. You have three ways out:

  • Use the old password, then change it properly with ALTER USER.
  • Reset it, as below, keeping your data.
  • If the data is disposable, a test database, remove the volume and let the image create a new one with the new password. This deletes everything in it.

To reset it, start a temporary container on the same volume in skip-grant mode, wait a few seconds for it to start, set both root accounts (the image creates root@localhost and root@%), then go back to your normal container:

docker stop shop-mysql
docker run --rm -d --name mysql-reset -v shop-data:/var/lib/mysql mysql:8.4 --skip-grant-tables
docker exec mysql-reset mysql -u root -e "FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY 'New-pass-3'; ALTER USER 'root'@'%' IDENTIFIED BY 'New-pass-3';"
docker stop mysql-reset
docker start shop-mysql

Update MYSQL_ROOT_PASSWORD in your compose file to match, so the next person isn't confused by it.

App accounts: wrong password, or the wrong account

For an app's account, (using password: YES) usually means just what it says. But there's one classic case where the password is right and MySQL compares it with a different account. An anonymous account, one with an empty user name, made for localhost, beats 'app'@'%' for connections from this machine, because MySQL picks the most specific host first:

sudo mysql -e "SELECT user, host FROM mysql.user WHERE user = '';"
User	Host
	localhost

A row like that means app on this machine is checked against the anonymous account, which has a different password, so it fails with 1045 every time. A fresh MariaDB on Amazon Linux 2023 has no anonymous accounts, but older installs and copied data sometimes do. Remove it, and the same login works:

sudo mysql -e "DROP USER ''@'localhost';"

If you inherited a server you didn't set up, also run sudo mariadb-secure-installation, which walks you through removing anonymous accounts and test databases.

RDS: reset the master password in one command

On RDS there's no --skip-grant-tables, and there doesn't need to be. Change the master password from outside the database:

aws rds modify-db-instance --db-instance-identifier shop-db --master-user-password 'New-Strong-Pass-4' --apply-immediately

This doesn't cause an outage; RDS applies the change in the background, as soon as it can. It also restores the master user's privileges if someone revoked them by accident, which makes it the way back in after a bad REVOKE, too. The password can use any printable ASCII character except /, " and @.

If the database stores its master password in AWS Secrets Manager, the command above is refused; read the current password from the secret instead:

aws rds describe-db-instances --db-instance-identifier shop-db --query "DBInstances[].MasterUserSecret.SecretArn" --output text
aws secretsmanager get-secret-value --secret-id <the ARN from above> --query SecretString --output text

A 1045 for a non-master RDS user is fixed the normal way: sign in as the master user and run ALTER USER.

Work through it in order

Most 1045 errors aren't a lost password, so resetting is the last step, not the first. Each check below takes seconds, and the first four solve the large majority of cases you'll run into. Start with the end of the message, because NO and YES send you down different paths, and check what the client actually sends before you change anything on the server:

  1. Read the ending: NO means add -p; YES means the password sent was wrong.
  2. Got 1698 for root on MariaDB? Use sudo mysql.
  3. Run mysql --print-defaults and echo $MYSQL_PWD for a stored password.
  4. Put passwords that contain $ in single quotes, or type them at the prompt.
  5. Docker: try the password from the first start.
  6. Look for anonymous accounts with user = ''.
  7. Still locked out: reset with --skip-grant-tables, or on RDS with --master-user-password.

Troubleshooting by symptom

sudo mysql gives ERROR 1045 (using password: NO)

Someone ran ALTER USER root IDENTIFIED BY on MariaDB, removing socket login. Sign in with the password, or reset it.

ERROR 1698 Access denied for user root@localhost

MariaDB's root signs in by system identity. Use sudo mysql, not mysql -u root -p.

New MYSQL_ROOT_PASSWORD doesn't work in Docker

The volume kept the password from the first start. Use the old one, or reset it.

using password: YES but I typed no password

A ~/.my.cnf file or the MYSQL_PWD variable sent one. Check mysql --print-defaults.

ERROR 1290 during the password reset

Run FLUSH PRIVILEGES first; in skip-grant mode, ALTER USER fails until you do.

Correct password, still 1045 from localhost

An anonymous ''@'localhost' account is being matched instead. Drop it.

MySQL ERROR 1045: frequently asked questions

What does ERROR 1045 Access denied for user root@localhost mean?

MySQL found an account that could match you, but the user name and password didn't match it.

What does (using password: NO) mean?

No password was sent. Add -p, or check whether the account needs one.

What does (using password: YES) mean?

A password was sent and it was wrong, or it was compared with a different account.

What is the MariaDB root password on Amazon Linux 2023?

There isn't one. Root signs in by system identity: run sudo mysql.

What is the difference between ERROR 1045 and ERROR 1698?

1045 is a password mismatch. 1698 is MariaDB refusing a socket-identity account, such as root, for the wrong Linux user.

Why does sudo mysql stop working after setting a root password?

On MariaDB, ALTER USER ... IDENTIFIED BY replaces socket login. Use IDENTIFIED VIA unix_socket OR mysql_native_password to keep both.

How do I reset the MySQL root password?

Restart with --skip-grant-tables (and --skip-networking on MariaDB), run FLUSH PRIVILEGES, then ALTER USER, then restart normally.

Why does ALTER USER fail with ERROR 1290?

The server is in skip-grant mode. Run FLUSH PRIVILEGES first.

Does --skip-grant-tables disable networking?

On MySQL 8.4, yes. On MariaDB 10.11, no: add --skip-networking yourself.

Why doesn't my new MYSQL_ROOT_PASSWORD work in Docker?

It only applies when the volume is empty. An existing database keeps its first password.

How do I reset the root password of MySQL in Docker?

Start a temporary container on the same volume with --skip-grant-tables, run FLUSH PRIVILEGES and ALTER USER for both root accounts.

How do I reset the RDS master password?

Run aws rds modify-db-instance with --master-user-password and --apply-immediately. It causes no outage.

My RDS master password is in Secrets Manager. How do I get it?

Get the secret ARN from describe-db-instances (MasterUserSecret), then read it with get-secret-value.

Why does a password with $ fail on the command line?

The shell changes it first. Put the password in single quotes, or type it at the prompt.

Where does mysql read a saved password from?

From option files such as ~/.my.cnf, and from MYSQL_PWD. mysql --print-defaults shows what it'll use.

What is an anonymous MySQL user?

An account with an empty user name. One for localhost can be matched before 'app'@'%' and cause 1045.

Why does the error say localhost when my user is 'app'@'%'?

The message shows where you connected from, not the host part of the account.

Ethan still knew the password he'd set, so he signed in with it and ran the IDENTIFIED VIA unix_socket OR mysql_native_password line, and sudo mysql worked again. Then he created a separate booking account for the app and stopped touching root altogether. Jake's verdict: "So you locked the front door with a key you didn't need, and the spare key was in your pocket the whole time." Ethan said that was about the size of it.

📌 If you keep one line from this page

Read the ending first: NO means no password was sent, YES means the wrong one was. On Amazon Linux 2023's MariaDB, root signs in with sudo mysql and has no password.

sudo mysql · mysql --print-defaults · FLUSH PRIVILEGES before ALTER USER · MYSQL_ROOT_PASSWORD = first start only · --master-user-password on RDS.

Revision note. Written October 14, 2026, for MariaDB 10.11 on Amazon Linux 2023, MySQL 8.4 and Amazon RDS. "If it ain't broke, don't fix it," as the saying goes; root's missing password was never broken.

Related