sodcalculator

10 Tech How-To

Fix MySQL Access Denied Errors on macOS

Guide 10-36746 · Updated · Step by step

If you are getting “Access denied for user” errors when connecting to MySQL on your local macOS development setup, the fix usually involves resetting your root password or creating a dedicated user with the correct privileges. This article walks you through the most common causes and step-by-step solutions, from stopping the MySQL service to using the skip-grant-tables mode safely.

Why MySQL Throws Access Denied

MySQL’s access control is based on user accounts and hostnames. When you connect, MySQL checks the username, the host you are connecting from, and the password. If any of these don’t match an entry in the mysql.user table, you get an “Access denied” error. On macOS, the most common triggers are:

  • You installed MySQL via Homebrew and the default root user has no password, but your client is sending one.
  • You set a root password earlier and forgot it.
  • The MySQL service was started with a different configuration (e.g., --skip-grant-tables left on).
  • You are connecting from ‘localhost’ but the user is defined for ‘127.0.0.1’ or vice versa.

Understanding this helps you choose the right fix instead of randomly trying commands.

First: Check Your Connection Command

Before resetting anything, verify how you are connecting. A common mistake is using mysql -u root when MySQL expects a password, or using mysql -u root -p when the password is empty. Try these in order:

  1. mysql -u root (no password)
  2. mysql -u root -p (then press Enter for empty password)
  3. mysql -u root -p (then type your known password)

If none work, move to the reset procedure below.

Reset Root Password via Skip-Grant-Tables

This is the standard recovery method. It temporarily starts MySQL without loading the grant tables, so you can log in without a password and set a new one. Here are the steps for a Homebrew installation (the most common on macOS):

  1. Stop MySQL: brew services stop mysql
  2. Start MySQL in safe mode: mysqld_safe --skip-grant-tables (run this in a separate terminal window, or use mysql.server start --skip-grant-tables)
  3. Open a new terminal and connect: mysql -u root
  4. Flush privileges: FLUSH PRIVILEGES;
  5. Set a new password. For MySQL 5.7+ and 8.0, use: ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword';
  6. Exit and restart MySQL normally: exit, then stop the safe-mode process (Ctrl+C) and run brew services start mysql

If you are using the official MySQL installer (dmg), the commands are similar but the service names differ (e.g., sudo /usr/local/mysql/support-files/mysql.server stop).

Create a Dedicated User Instead

Often the best long-term fix is to create a new user with just the privileges you need, rather than relying on root. This avoids permission issues and is safer. After logging in as root (after the reset), run:

CREATE USER 'devuser'@'localhost' IDENTIFIED BY 'devpassword';
GRANT ALL PRIVILEGES ON *.* TO 'devuser'@'localhost';
FLUSH PRIVILEGES;

Then connect with mysql -u devuser -p. This is especially useful if your application code uses a specific user and you want to avoid the root account entirely.

Common Pitfalls and Misconceptions

One frequent issue is that after using --skip-grant-tables, you must run FLUSH PRIVILEGES; before ALTER USER; otherwise, MySQL may not recognize the command. Another is that on some systems, the root user is defined for ‘localhost’ only, so connecting via ‘127.0.0.1’ fails. Check the host column in mysql.user.

Also, don’t confuse the macOS system password with the MySQL root password. They are independent. If you just installed MySQL, the root password might be empty, but the installer may have set a temporary one in a file like /usr/local/mysql/data/error.log (look for “temporary password”).

Alternatives and Preventative Measures

Instead of resetting, you can reinstall MySQL, but that loses your databases. A better approach is to use a configuration file to set a default user and password for your development environment, so you don’t have to type them each time. For example, add to ~/.my.cnf:

[client]
user=devuser
password=devpassword

Then just run mysql and it connects automatically. Just ensure the file permissions are set to 600 (chmod 600 ~/.my.cnf) to keep it secure.

Frequently Asked Questions

Why does ‘Access denied for user ‘root’@’localhost” appear even when I use the correct password?

This usually means the password is not actually correct, or the user ‘root’@’localhost’ does not exist. Check the user table with SELECT User, Host FROM mysql.user; after logging in via skip-grant-tables. If the host is ‘127.0.0.1’ instead of ‘localhost’, try connecting with mysql -h 127.0.0.1 -u root -p.

Can I use skip-grant-tables permanently?

No. Running MySQL with --skip-grant-tables disables all access control, which is extremely dangerous in any environment. Use it only for recovery, and always restart MySQL normally afterward.

What if I get ‘ERROR 1045 (28000): Access denied’ when trying to reset the password?

This often happens if you didn’t run FLUSH PRIVILEGES; after starting with skip-grant-tables. Run it first, then try the ALTER USER command again. Also ensure you are using the correct syntax for your MySQL version (MySQL 8.0 uses IDENTIFIED BY, not PASSWORD()).

How do I stop mysqld_safe that I started in a terminal?

Press Ctrl+C in the terminal where it is running. If that doesn’t work, open another terminal and run mysqladmin shutdown -u root -p (after you have reset the password) or brew services stop mysql.

Is it safe to delete the mysql.user table to reset everything?

No. Deleting the table will break MySQL completely. The proper way is to use the skip-grant-tables method, which preserves the table structure.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →