InletDownload

MySQL error 1045

ERROR 1045 (28000): Access denied for user

The server didn’t accept the user, password and client address you connected with. MySQL gives the same message for a wrong password, an unknown user and an account that only exists for another host.

ERROR 1045 (28000): Access denied for user 'seo_mysql_app'@'127.0.0.1' (using password: YES)

Tested on MySQL 8.4.11 and MariaDB 11.4.13 · Updated 9 October 2026

What it means

An account in MySQL and MariaDB is a user and a host: 'app'@'%' and 'app'@'localhost' are two different accounts, each with its own password. When you connect, the server takes the most specific account whose host matches the address it sees you coming from, and checks your password against that one account. Error 1045 means the check failed.

The message is the same whether the password is wrong, the user doesn’t exist, or the user exists only for some other host. Two parts of it tell you more:

  • 'app'@'127.0.0.1' is the user name you sent and the address the server saw. It isn’t necessarily an account that exists.
  • (using password: NO) means your client sent no password at all. The password never reached the client: an empty environment variable, a missing -p, a config file that wasn’t read.

Common causes

  1. The password is wrong: a typo, an old password, or one read from a file or environment variable with a trailing newline or space.
  2. No password was sent (using password: NO).
  3. The account is for a different host. 'app'@'localhost' doesn’t match a TCP connection from another machine, and from your Mac to a server in Docker the server sees the Docker network’s gateway address (it was 192.168.148.1 here), not localhost.
  4. A more specific account matches first. With both 'app'@'%' and 'app'@'10.0.0.5', a connection from 10.0.0.5 is checked only against the second one and its password.
  5. The user doesn’t exist on this server: a different server, port or container than you think, or a Docker volume that kept an older database.
  6. Special characters in a connection URL that weren’t percent-encoded, so the client sent a different password from the one you typed.

How to fix it

See which accounts exist for that user

Connect as an administrator and list every host the user has:

SELECT user, host, plugin FROM mysql.user WHERE user = 'app' ORDER BY host;

Compare the host column with the address in the error. % matches any address. With skip_name_resolve on (the official MySQL and MariaDB Docker images turn it on), localhost matches only connections through the Unix socket; a TCP connection to 127.0.0.1 is checked against a 127.0.0.1 or % account instead.

Once you can sign in, this shows who you asked to be and which account the server actually used:

SELECT USER(), CURRENT_USER();

Reset the password

Name the exact user and host from the list above:

ALTER USER 'app'@'%' IDENTIFIED BY '<new password>';

If the user has several hosts, each has its own password. Set the one you connect through.

Add an account for the address you connect from

If the user exists only for localhost and you connect over TCP (from another machine, or from your Mac into Docker), create one for that address, or for %:

CREATE USER 'app'@'%' IDENTIFIED BY '<password>';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'app'@'%';

Before you do, check for a more specific account that would still win for your address, and drop it if it’s stale.

Make sure a password is sent

With the mysql client, -p alone makes it ask; -p<password> takes no space. If the password comes from an environment variable or a .env file, check it isn’t empty and has no newline at the end. mysql --no-defaults ignores option files such as ~/.my.cnf, which can hold an old password.

Docker: the first start sets the password

The official MySQL and MariaDB images read MYSQL_ROOT_PASSWORD (or MARIADB_ROOT_PASSWORD), MYSQL_USER and the rest only when the data directory is empty. If the volume already has a database, changing those variables does nothing and the old passwords still apply. Sign in with the old one and run ALTER USER, or remove the volume if its data is disposable.

Encode special characters in URLs

In a mysql:// URL, @, :, /, ?, # and % in the password must be percent-encoded: p@ss:word becomes p%40ss%3Aword. See special characters in passwords.

Error 1698 instead: socket authentication

An account that uses MariaDB’s unix_socket plugin (or MySQL’s auth_socket) checks your operating-system user, not a password. MariaDB 10.4 and later create root@localhost that way, so mysql -u root as a different OS user fails with a different number:

ERROR 1698 (28000): Access denied for user 'seo_mysql_sock'@'localhost'

Run the client as the matching OS user (sudo mariadb for root), or give the account a password.

Reproduce it

On MySQL 8.4.11, with an account 'seo_mysql_app'@'%', from the mysql client in the server’s container:

mysql -h127.0.0.1 -useo_mysql_app -pwrong -e 'select 1'
ERROR 1045 (28000): Access denied for user 'seo_mysql_app'@'127.0.0.1' (using password: YES)

A user that doesn’t exist gets the same message, and leaving out -p changes only the end:

ERROR 1045 (28000): Access denied for user 'nobody'@'127.0.0.1' (using password: YES)
ERROR 1045 (28000): Access denied for user 'seo_mysql_app'@'127.0.0.1' (using password: NO)

An account 'seo_mysql_local'@'localhost' with the right password, over TCP:

ERROR 1045 (28000): Access denied for user 'seo_mysql_local'@'127.0.0.1' (using password: YES)

The same account through the socket (-hlocalhost) signs in. Then, after adding 'seo_mysql_app'@'127.0.0.1' with a different password, the % account’s password stopped working from 127.0.0.1 with the same 1045, and the new one worked:

select user(), current_user();
user()	current_user()
seo_mysql_app@127.0.0.1	seo_mysql_app@127.0.0.1

MariaDB 11.4.13 gave the same messages, number and SQLSTATE in every case. It also writes each refusal to its error log, which MySQL 8.4 didn’t at its default log_error_verbosity of 2:

[Warning] Access denied for user 'seo_mysql_app'@'127.0.0.1' (using password: YES)

In Inlet

When the server refuses the password, the connection window shows the server’s message and asks for the password right there; once the server accepts it, Inlet can save it in the Keychain. You can also paste a mysql:// URL and Inlet fills in the form, so you can check the user, host and port before you connect.

Related

Sources