ERROR 1045 (28000)

MySQL 1045 Access Denied: Fix in 5 Minutes Flat

MySQL throws 1045 when auth fails. Usually a typo in user/host, a bad password, or the user's host mismatch. Here's how to find and fix it fast.

Quick answer

Run mysql -u root -p and if that fails, the user or host is wrong, or the password. Check SELECT user, host FROM mysql.user; and reset the password if stuck.

Why this happens

MySQL is picky about who connects from where. The error ERROR 1045 (28000): Access denied for user 'root'@'localhost' means MySQL looked at your username, the host you're connecting from, and your password—and one of those didn't match the user table. It's not a server-down issue; it's an authentication failure.

Most of the time it's a typo in the password, or you're connecting as root but the root user only exists for localhost and you're hitting it via a different IP. Another classic: you installed MySQL and never set a root password, so the default is empty—and then you type something else.

What's actually happening here is that MySQL matches the user and host exactly from the mysql.user table. There's no fallback. If the host doesn't match (say you're connecting from 192.168.1.5 but the row says localhost), it denies you. Even a wildcard like % won't help if there's a more specific row that blocks you.

Fix steps

  1. Verify the exact error message. Read it carefully. It tells you the user and host. For example, 'root'@'localhost' vs 'root'@'192.168.1.5'. That's your first clue.
  2. Try the simplest login:
    mysql -u root -p
    If it asks for a password, type it. If it fails, try with no password:
    mysql -u root
    If that works, the password was wrong. Reset it with the steps below.
  3. Check the user table. If you can log in somehow (even as another user), run:
    SELECT user, host FROM mysql.user;
    You'll see rows like root | localhost and maybe root | %. If you're connecting to a server by IP and there's no matching host, that's your problem.
  4. Reset the root password. If you're locked out entirely, you need to restart MySQL with --skip-grant-tables. On Ubuntu/Debian:
    sudo systemctl stop mysql
    sudo mysqld_safe --skip-grant-tables &
    Then connect without a password:
    mysql -u root
    Now flush privileges and set a new password:
    FLUSH PRIVILEGES;
    ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass123!';
    FLUSH PRIVILEGES;
    Then restart MySQL normally: sudo systemctl start mysql
  5. If the host is the issue, create the right user. Instead of changing root, just add a user for your network:
    CREATE USER 'root'@'192.168.1.%' IDENTIFIED BY 'yourpass';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    That allows root to connect from any IP in that subnet.

Alternative fixes if the main one fails

  • Check the password with mysql_config_editor. If you're using a login path, it may store an outdated password. Remove it: mysql_config_editor remove --login-path=client
  • Look for auth_socket vs mysql_native_password. On fresh Ubuntu installs, root uses auth_socket, which only allows sudo mysql. If you try mysql -u root -p, it fails. Fix it by running sudo mysql and then:
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'NewPass123!';
    This is a common gotcha on Ubuntu 20.04 and later.
  • Check if MySQL is actually running. Sounds dumb, but I've seen people get 1045 when the server was stopped and they were hitting a stale socket. Run sudo systemctl status mysql.
  • Try connecting via TCP/IP explicitly. Sometimes the socket is the default, and the socket file path is wrong. Use mysql -h 127.0.0.1 -P 3306 -u root -p to force TCP.

Prevention

The real fix is to stop guessing. Write down your passwords in a password manager, and always define the host when you create a user. If you're setting up a new server, do this right away:

CREATE USER 'app'@'localhost' IDENTIFIED BY 'strongpass';
CREATE USER 'app'@'%' IDENTIFIED BY 'strongpass';
GRANT ALL PRIVILEGES ON mydb.* TO 'app'@'localhost';
GRANT ALL PRIVILEGES ON mydb.* TO 'app'@'%';

That covers both local and remote, no surprises. Also set a root password immediately after install—don't leave it blank. And if you ever change a password, update any config files or environment variables that reference it. Trust me, a forgotten .env file will bite you at 2 AM.

One more thing: never use --skip-grant-tables on a production server unless you have no other choice. It opens the door completely. If you must, make sure to flush privileges and set a new password before restarting.

Related Errors in Database Errors
0X000010DA Fix ERROR_DATABASE_FULL 0X000010DA on SQL Server 0XC01C001B STATUS_FLT_ALREADY_ENLISTED (0XC01C001B) fix 0X00001A40 Fix 0x1A40 Transaction Manager Name Collision on SQL Server FATAL: role 'username' does not exist Postgres Role Does Not Exist Error Fix

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.