VPS Snaps

How to reset the MySQL or MariaDB root password

On Ubuntu and Debian, try sudo mysql first: root usually logs in through the Unix socket with no password, and you can set a new one from there. If that fails, restart the server once with an init file containing ALTER USER 'root'@'localhost' IDENTIFIED BY 'new-password';, then restart it normally. --skip-grant-tables works too, but leaves every account open while it runs.

9 min readUpdated Checked against official documentation

First, try sudo

Terminal
sudo mysql

If you get a mysql> or MariaDB [(none)]> prompt, you are in as root and nothing needs resetting. Two defaults make this work:

  • Ubuntu's MySQL packages (8.0 on 24.04, 8.4 on 26.04) give root the auth_socket plugin when installed without a root password. The server checks that the Linux user on the other end of the socket is also called root; no password is involved.
  • MariaDB 10.4 and later create root@localhost with unix_socket OR mysql_native_password, the password half set to an invalid value. MariaDB's own documentation: if you've forgotten your root password, you can still connect using sudo and change it.

That is also why a normal user who types mysql -u root -p gets ERROR 1698 (28000): Access denied for user 'root'@'localhost' whatever password they enter: there is no password to match.

Ubuntu's MySQL packages give you a second way in. They create a debian-sys-maint account with every privilege and keep its login in a file only root can read, so this works even when root has a password nobody remembers:

Terminal
sudo mysql --defaults-file=/etc/mysql/debian.cnf

On Debian's and Ubuntu's MariaDB packages that file names root itself, so it only helps while root still has socket login.

Set the new password once you are in

First list the root accounts. A password set for root@localhost does not change root@'%' or [email protected]:

MySQL / MariaDB prompt
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';

On MySQL:

MySQL prompt
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new-password';

Without a WITH clause, this also switches the account to the default authentication plugin. On Ubuntu that moves root off auth_socket, so from then on root needs the password even with sudo: sudo mysql -u root -p.

On MariaDB, use SET PASSWORD, which MariaDB's documentation gives for root. It fills in the password half of root's login and leaves socket login in place:

MariaDB prompt
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new-password');

On MariaDB, ALTER USER ... IDENTIFIED BY replaces every login method the account has. Root loses unix_socket, and anything that relies on it, such as the maintenance login in /etc/mysql/debian.cnf, stops working. If that already happened, restore both: ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('new-password');

Skip old guides that run UPDATE mysql.user SET password=PASSWORD(...): MySQL 8 has no PASSWORD() function, and since MariaDB 10.4 mysql.user is a view over mysql.global_priv. On a fresh install from MySQL's own RPM repositories, root starts with a temporary password written to the log. Log in with it, then run the ALTER USER above:

Terminal
sudo grep 'temporary password' /var/log/mysqld.log

If no login works, have the server run one statement as it starts. This is the first method in MySQL's manual, and the server never runs without authentication. On Ubuntu and Debian, mysql.service starts /usr/sbin/mysqld with no way to add options, so pass the file through a config snippet. The same steps work for MariaDB.

Write the statement on one line, ending with a semicolon. On MariaDB, use the SET PASSWORD line from the previous section instead:

/etc/mysql/reset-root.sql
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new-password';
Terminal
sudo chown mysql:mysql /etc/mysql/reset-root.sql
Terminal
sudo chmod 600 /etc/mysql/reset-root.sql

The server runs as the mysql user, which must be able to read the file. Keep it under /etc/mysql: on Ubuntu, AppArmor lets MySQL read only its own directories, and MariaDB's service runs with ProtectHome=true, which hides /home and /root from the server.

/etc/mysql/conf.d/zz-reset-root.cnf
[mysqld]
init-file=/etc/mysql/reset-root.sql
Terminal
sudo systemctl restart mysql

On MariaDB the service is mariadb. Log in with the new password:

Terminal
mysql -u root -p

Then delete both files, so the password is not left on disk and the statement does not run at every start, and restart once more to confirm the server comes up cleanly without them:

Terminal
sudo rm /etc/mysql/conf.d/zz-reset-root.cnf /etc/mysql/reset-root.sql
Terminal
sudo systemctl restart mysql

If the server does not come back, read why before trying anything else: sudo tail -n 50 /var/log/mysql/error.log for Ubuntu's MySQL, sudo journalctl -u mariadb -n 50 for MariaDB. A typo in the SQL file or a file the server cannot read is the usual cause.

Reset it with --skip-grant-tables

The other official method starts the server with no privilege checks at all. It is easiest where the service passes extra options from a MYSQLD_OPTS variable: MySQL's own mysqld.service on RHEL-family systems and MariaDB's mariadb.service. Ubuntu's and Debian's mysql.service ignores that variable; there, put a skip-grant-tables line under [mysqld] in the snippet above instead of init-file, and restart mysql.

Terminal
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"

On MariaDB, use MYSQLD_OPTS="--skip-grant-tables --skip-networking" (or add a skip-networking line to the snippet), and restart mariadb instead of mysqld below. MySQL 8 turns off TCP connections by itself when grant tables are skipped; MariaDB does not, and without --skip-networking anyone who can reach port 3306 gets in as any user.

Terminal
sudo systemctl restart mysqld
Terminal
mysql -u root
MySQL prompt
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new-password';

FLUSH PRIVILEGES loads the grant tables again; until it runs, account statements fail with error 1290. On MariaDB, follow it with the SET PASSWORD line instead of ALTER USER. Then clear the variable (or delete the snippet) and restart normally:

Terminal
sudo systemctl unset-environment MYSQLD_OPTS
Terminal
sudo systemctl restart mysqld

Older guides start the server with mysqld_safe --skip-grant-tables &. Where MySQL runs under systemd, mysqld_safe is not installed, so that command fails.

Reset it in Docker

Changing MYSQL_ROOT_PASSWORD or MARIADB_ROOT_PASSWORD and restarting does nothing once the data directory holds a database: the images read those variables only when they set up an empty one. Stop the database container, then run a one-off server on the same data with --init-file, the method MariaDB documents for its image. The MySQL image creates 'root'@'%' as well as 'root'@'localhost', and MariaDB's template sets both too, so change both:

passwordreset.sql
ALTER USER IF EXISTS 'root'@'localhost' IDENTIFIED BY 'new-password';
ALTER USER IF EXISTS 'root'@'%' IDENTIFIED BY 'new-password';

For the mariadb image, write the two lines as SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new-password'); and the same for 'root'@'%'. The server inside the container does not run as your user, so make the file readable with chmod 644, and delete it afterwards. Use the image tag your container already runs, not a newer one:

Terminal
docker run -d --rm --name pwreset -v /my/own/datadir:/var/lib/mysql -v /my/own/passwordreset.sql:/passwordreset.sql:z mysql:8.4 --init-file=/passwordreset.sql

Arguments after the image name go to the server, and the command is the same for mariadb: tags. If the data lives in a named volume, put the volume's name (from docker volume ls) in place of the directory. When docker logs pwreset shows the server is ready for connections, stop it and start your usual container:

Terminal
docker stop pwreset

Then update the password in your Compose file or secrets, so the next person who reads it is not misled. Backing up the database itself is covered in Docker Compose database backups.

Managed databases

Amazon RDS, DigitalOcean and other managed services do not give you the real root account or SUPER, and you cannot restart them with special options. Reset the admin user through the provider:

  • Amazon RDS: modify the instance and set a new master password in the console, or with the command below. It applies as soon as possible, without downtime. If AWS Secrets Manager manages the password, rotate the secret instead.
  • DigitalOcean Managed MySQL: in the control panel, open the user's More menu and choose Reset password.
Terminal
aws rds modify-db-instance --db-instance-identifier mydb --master-user-password 'new-password'

The console keeps the password out of your shell history. For keeping copies of a managed database in storage you control, see managed database backups.

Afterwards: update everything that uses it

A new root password breaks every program still sending the old one. Check:

  • Application config files (.env, wp-config.php and the like) that log in as root.
  • ~/.my.cnf and other option files.
  • Cron jobs and scripts that run mysqldump or mysql.
  • Backup jobs and monitoring that connect as root.

Better still, stop using root for any of them. Give each application its own account limited to its database, and give backups a dedicated read-only user; the mysqldump guide lists the grants it needs. Then a root password change touches nothing else, and a leaked application password does not hand over the whole server. On Ubuntu's MySQL packages, package upgrades log in as debian-sys-maint, so they are unaffected either way.

Common errors

ErrorCause and fix
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)Wrong password for that account. If no other login works, use the init file method. (using password: NO) means no password was sent; add -p.
ERROR 1698 (28000): Access denied for user 'root'@'localhost'Root uses socket authentication. Run the client as Linux root: sudo mysql.
ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statementRun FLUSH PRIVILEGES; first, then repeat the statement. MariaDB words it The MariaDB server is running with the --skip-grant-tables option.
ERROR 1819 (HY000): Your password does not satisfy the current policy requirementsThe validate_password component is active, as it is on MySQL's RPM installs. Use at least 8 characters with upper and lower case letters, a digit and a symbol.
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.The password has expired, as a new install's temporary password has. Run ALTER USER for your own account before anything else.
ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'localhost'That user and host pair does not exist. List them with SELECT user, host FROM mysql.user; and use the exact host.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)The server is not running, often because it failed to start with your change. Read its error log, fix the cause and start it again. MariaDB's client says Can't connect to local server through socket.

Frequently asked questions

Does resetting the MySQL root password affect my data?
No. It changes one account's credentials; databases, tables and other users are untouched. Programs that logged in as root with the old password stop connecting until you update them.
What is the default MySQL root password?
There is none to look up. Ubuntu's MySQL packages and MariaDB 10.4+ let root in through the socket with sudo mysql, MySQL's RPM installs write a temporary password to /var/log/mysqld.log, and the Docker images use the password you set the first time the container started.
Why does sudo mysql work without a password?
Root uses socket authentication (auth_socket on MySQL, unix_socket on MariaDB): the server checks that the Linux user connecting through the socket is root, instead of asking for a password.
How do I reset the root password on Amazon RDS?
You cannot reach the real root account. Set a new master password by modifying the instance in the console or with aws rds modify-db-instance --master-user-password.
Is --skip-grant-tables safe?
Only for a few minutes: every account gets in with no password while it runs. MySQL 8 refuses TCP connections in that mode, but MariaDB needs --skip-networking added. The init file method avoids the open window entirely.

How this was checked

Commands, limits and prices were checked against these official pages, on October 4, 2026: