Locked out of MySQL? Before doing anything drastic, check whether you need a password at all: on Ubuntu and Debian, root often logs in with socket authentication. If that doesn’t work, you can reset the password with the server started in a special mode. You need root (or sudo) access to the Linux server.
Step 0: try sudo mysql
sudo mysql
If you get a mysql> or MariaDB [(none)]> prompt, root uses auth_socket / unix_socket and has no password to lose. You can manage everything from here, including creating a password-based admin user:
CREATE USER 'dba'@'localhost' IDENTIFIED BY 'New-Strong-Password';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'localhost' WITH GRANT OPTION;
If you specifically need root to accept a password (for example, a legacy tool), set one:
-- MySQL 8
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'New-Strong-Password';
-- MariaDB
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('New-Strong-Password');
The MariaDB form keeps socket login and adds a password.
If sudo mysql is refused: reset with –skip-grant-tables
This starts the server without checking privileges, so anyone who can connect gets full access. We combine it with --skip-networking so only local socket connections work while you fix the password.
1. Stop the server
sudo systemctl stop mysql # MySQL on Ubuntu/Debian
sudo systemctl stop mariadb # MariaDB
sudo systemctl stop mysqld # MySQL on AlmaLinux/Rocky
2. Start it in recovery mode
The cleanest way on systemd systems is to pass options through an environment variable:
# MySQL
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mysql
# MariaDB
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mariadb
If your MySQL unit doesn’t read MYSQLD_OPTS, start the daemon by hand instead:
sudo mkdir -p /var/run/mysqld && sudo chown mysql: /var/run/mysqld
sudo mysqld_safe --skip-grant-tables --skip-networking &
3. Log in and set the password
sudo mysql -u root
The grant tables aren’t loaded, and ALTER USER refuses to run until you reload them:
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'New-Strong-Password';
EXIT;
On very old servers (MySQL 5.6 and earlier) the syntax is SET PASSWORD FOR 'root'@'localhost' = PASSWORD('…');.
4. Return to normal mode
sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl restart mysql # or mariadb / mysqld
If you used mysqld_safe, stop it first: sudo mysqladmin -u root -p shutdown, then start the service normally.
5. Test
mysql -u root -p
Common errors
ERROR 1290: The MySQL server is running with the --skip-grant-tables option — you ran ALTER USER before FLUSH PRIVILEGES. Run the flush first.
ERROR 1819: Your password does not satisfy the current policy requirements — the validate_password component is active. Use a longer password with mixed character types.
Plugin 'auth_socket' is not loaded — happens if you try to set socket authentication while grant tables are skipped. Set a password first, restart normally, then adjust the plugin.
Root still can’t log in remotely — that’s by design. root@localhost only accepts local connections; use an SSH tunnel or a separate admin account.
Recovering an application password
You don’t need recovery mode for app users. As root (or via sudo mysql):
ALTER USER 'wpuser'@'localhost' IDENTIFIED BY 'New-Password';
Then update the app’s configuration (for WordPress, DB_PASSWORD in wp-config.php). Often you don’t need to reset anything — the current password is in that config file.
Prevent it next time
- Keep root on socket authentication, and create a named admin user with a password stored in your password manager.
- Store app credentials in config files readable only by the app user (
chmod 640). - Keep
/root/.my.cnfwith credentials for scripts, mode600.
Getting started with MySQL? See installing MySQL on Ubuntu and MySQL users and privileges. If you’ve lost access to the whole server rather than just MySQL, VPS.DO plans include a VNC console in the client area, which works even when SSH doesn’t.