MySQL error 1045 (Access Denied for User) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Check the exact user@host MySQL matched: the message includes the account and the client host. If that does not apply, verify the password: `ALTER USER 'app'@'localhost' IDENTIFIED BY '...'` after any reset — the full checklist is below.
MySQL Error Code: 1045
Official name: Access Denied for User
Service: MySQL
Access denied for user '%s'@'%s' (using password: %s)
mysql -u app -p -h 127.0.0.1 mydb
# if 'Access denied', the account/host/password combo is wrong
Reproducing with the CLI isolates config problems from code problems.
CREATE USER 'app'@'10.0.0.%' IDENTIFIED BY 'secret';
GRANT ALL PRIVILEGES ON mydb.* TO 'app'@'10.0.0.%';
FLUSH PRIVILEGES;
Creates the account for the app server's network and grants access to the schema it needs.
Keep credentials in env vars and log only the user@host part of the error, never the password.
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
})
Check the URL parts (host/user/db) and confirm the account host mask matches the app server.
# mysql+pymysql://user:pass@host:3306/dbname
# 'Access denied' -> verify user/pass and host mask
Wrap connect in try/catch and surface a friendly message while logging the real error.
try {
$pdo = new PDO('mysql:host=' . $host . ';dbname=' . $db, $user, $pass);
} catch (PDOException $e) {
error_log($e->getMessage());
exit('Database connection failed');
}
Most often this happens when wrong password in the connection string or config file, or when the MySQL user does not exist, or exists only for a different host (user@'localhost' vs connecting remotely).
Check the exact user@host MySQL matched: the message includes the account and the client host.
This page documents fixes for: nodejs-mysql2, python-sqlalchemy, php-pdo.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official MySQL documentation linked below and adds practical troubleshooting guidance on top.