TechEarl

How to Reset a Forgotten MySQL Root Password

Reset a forgotten MySQL root password using --skip-grant-tables, an init-file, or my.cnf. Step-by-step for MySQL 5.7, 8.0, and the changes that landed in 8.4.

Ishan KarunaratneIshan Karunaratne⏱️ 8 min readUpdated
Macro close-up of an old brass padlock with the shackle slightly open on a dark slate surface lit by a single warm side lamp

Three ways to reset a forgotten MySQL root password: start the server with --skip-grant-tables (the classic, works on every version), point the server at an init-file with the new password statement (cleaner, no permission-table tricks), or edit my.cnf for a permanent reset on a controlled box. The exact ALTER USER syntax depends on whether you are on MySQL 5.7, 8.0, or 8.4, and which authentication plugin is in use. I will walk all three, with the version-specific gotchas called out.

The kind of server where this comes up is the one nobody has touched in years: someone provisioned it, set a strong root password, stored it somewhere that no longer exists, and now you have shell access but no mysql credentials. Every method below assumes you have shell access as a user that can stop and start the mysqld process (typically root or whoever owns the data directory). Without that, the recovery options are different and usually involve restoring from a backup.

Try it with your own values

Jump to:

Method 1: --skip-grant-tables (all versions)

The classic. Tell MySQL to start without loading the privilege tables, log in with no password, change the root password, then restart normally.

BASH
# Stop MySQL
sudo systemctl stop mysql       # or: sudo service mysql stop

# Start with privilege checks bypassed and no networking
sudo mysqld_safe --skip-grant-tables --skip-networking --socket=:db_socket &

# Connect without a password
mysql -u root --socket=:db_socket

Once you are at the mysql> prompt, set the new password. The exact statement depends on your version:

SQL
-- MySQL 8.0 and 8.4
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY ':new_password';

-- MySQL 5.7
UPDATE mysql.user
SET authentication_string = PASSWORD(':new_password')
WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;

The FLUSH PRIVILEGES before the ALTER USER is the one most guides skip and the one that bites you on 8.x. Without it, the running server still has the privilege tables in --skip-grant-tables mode and ALTER USER errors out with "The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement". The flush re-enables the privilege subsystem for the rest of your session.

Exit the mysql client, kill the running mysqld_safe process, and start the server normally:

BASH
# Kill the recovery instance
sudo pkill -u mysql mysqld

# Start MySQL normally
sudo systemctl start mysql

# Verify the new password works (you will be prompted for :new_password)
mysql -u root -p --socket=:db_socket

This method works on every MySQL version including 5.5, 5.6, 5.7, 8.0, 8.1, 8.2, 8.3, and 8.4. It is also the one that survives the most weird edge cases (corrupted auth plugin, missing socket, mismatched ownership on mysql.sock).

Method 2: --init-file (cleaner, no live SQL needed)

If you prefer not to leave a --skip-grant-tables instance running while you type, write the password change to a file and tell MySQL to execute it at startup.

BASH
# Create the init file with the password statement
sudo tee :init_file <<EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY ':new_password';
EOF
sudo chown mysql:mysql :init_file
sudo chmod 600 :init_file

# Start MySQL with the init file
sudo systemctl stop mysql
sudo mysqld --user=mysql --init-file=:init_file &

# Once MySQL is up, stop it and start normally
sudo pkill -u mysql mysqld
sudo systemctl start mysql

# Remove the init file
sudo rm :init_file

The init-file is read once at server startup and the SQL inside runs with full privileges before any client can connect. It avoids the --skip-grant-tables window where the server is technically running without authentication, which matters on a shared box.

On MySQL 5.7, replace the ALTER USER line with the 5.7 syntax shown in Method 1.

Method 3: my.cnf with mysql_native_password (permanent reset)

When you are setting up a fresh box and want the root password defined in config rather than typed, add it to my.cnf and let it persist across restarts. This is also the workaround for a class of MySQL 8.0+ problems where the default caching_sha2_password plugin fights with old clients.

INI
# /etc/mysql/my.cnf  (or /etc/my.cnf on RHEL/CentOS)
[mysqld]
init-file = /etc/mysql/mysql-init.sql
default_authentication_plugin = mysql_native_password

Then create the init file:

BASH
sudo tee /etc/mysql/mysql-init.sql <<EOF
ALTER USER 'root'@'localhost'
IDENTIFIED WITH mysql_native_password BY ':new_password';
EOF
sudo chown mysql:mysql /etc/mysql/mysql-init.sql
sudo chmod 600 /etc/mysql/mysql-init.sql

sudo systemctl restart mysql

Note: mysql_native_password was deprecated in MySQL 8.0 and is no longer the default. In MySQL 8.4 it was removed from the default install entirely and you have to enable it explicitly with --mysql-native-password=ON or by installing the plugin. If you are on 8.4+, prefer caching_sha2_password unless you have legacy clients that cannot speak it.

Version compatibility: 5.7, 8.0, 8.4

VersionReleasedReset worksAuth-plugin defaultWatch out for
MySQL 5.52010Method 1 only (5.7 syntax)mysql_native_passwordUse UPDATE mysql.user and PASSWORD()
MySQL 5.62013Method 1 (5.7 syntax)mysql_native_passwordSame as 5.5
MySQL 5.72015All methods (5.7 syntax)mysql_native_passwordauthentication_string column replaces password
MySQL 8.02018All methods (8.0 syntax)caching_sha2_passwordFLUSH PRIVILEGES before ALTER USER
MySQL 8.42024All methods (8.0 syntax)caching_sha2_passwordmysql_native_password requires explicit enable

The most common surprise on a 5.7 → 8.0 upgrade is the syntax shift: 5.7 uses UPDATE mysql.user with PASSWORD(), 8.0+ uses ALTER USER ... IDENTIFIED BY. The two are not interchangeable.

Verify and re-lock the server

After the reset, log in with the new password and confirm both the user and the auth plugin look right:

SQL
SELECT User, Host, plugin FROM mysql.user WHERE User = 'root';

You should see one row per root user. Each plugin should be either caching_sha2_password (8.0+ default) or mysql_native_password (5.7 and earlier, or by choice). If plugin shows auth_socket, that root account is using socket authentication and cannot be logged into with a password — you would log in as the OS root user instead.

Two final hardening steps for a fresh server:

  • Delete the --init-file from disk if you used Method 2 with /tmp/mysql-init.sql. The password is in plaintext inside it.
  • Run mysql_secure_installation to remove the test database, disallow remote root login, and remove anonymous accounts.

What to do next

The reset gets you back in; the operational follow-up is locking down what root can do and creating per-application users with the minimum privileges they need. The MySQL Cheat Sheet covers the syntax for CREATE USER, GRANT, REVOKE, and the privilege names you will be choosing from.

If the reason you ended up locked out was a WordPress site whose database password also got lost, the WordPress side has its own reset path: How to Change a WordPress Password (4 Methods) covers the dashboard, WP-CLI, direct database, and email-reset routes for the WP user table.

External reference: the official documentation on resetting the MySQL root password and MySQL 8.4 authentication plugin changes.

FAQ

See also

TagsMySQLDatabasePassword ResetRoot PasswordMySQL AdminAuthenticationSecurity
Share
Ishan Karunaratne

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years across software, Linux systems, DevOps, and infrastructure — and a more recent focus on AI. Currently Chief Technology Officer at a tech startup in the healthcare space.

Keep reading

Related posts

Four reliable ways to change a WordPress password: admin dashboard, WP-CLI, direct in the database, or email reset. Includes the WP 6.8+ bcrypt hash format.

How to Change a WordPress Password

Four reliable ways to change a WordPress password: admin dashboard, WP-CLI, directly in the database with the correct phpass or bcrypt hash, and the lost-password email reset.

Macro photograph of a stack of paper documents on a dark slate desk with a single sheet pulled out and crumpled to the side, warm amber side light

How to Delete Duplicate Rows in MySQL

Delete duplicate rows in MySQL while keeping one per group, using DELETE JOIN, ROW_NUMBER with CTE, or the safe temp-table swap. With dry-run, transactions, and rollback.