# ERROR 1698 (28000): Access Denied for User 'root'@'localhost' in MySQL

Source: https://www.bytebase.com/reference/mysql/error/1698-access-denied-for-user-auth-socket/

---

## Error Message

```sql
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

You may hit the same code for a non-root account, and on MariaDB the wording is identical:

```
ERROR 1698 (28000): Access denied for user 'admin'@'localhost'
```

## What Triggers This Error

1698 reads like a wrong-password error. It usually isn't. The giveaway is that it appears with no `(using password: YES)` suffix, unlike [ERROR 1045](/reference/mysql/error/1045-access-denied-for-user-using-password/). That suffix is missing because the account isn't checking a password at all.

On Debian, Ubuntu, and most MariaDB packages, the `root` account is created with the `auth_socket` plugin (called `unix_socket` on MariaDB). That plugin ignores any password you type and instead checks the operating-system user running the client. If your OS user name matches the MySQL user name, you're in. If it doesn't, you get 1698. So `mysql -u root -p` typed as a normal Linux user fails every time, no matter what password you enter.

The fix depends on which situation you're in:

- **Fresh install, connecting from the shell as a non-root OS user:** the account is on `auth_socket` and you're not the OS `root`.
- **An app or ORM connecting over TCP as `root` with a password:** `root@localhost` is socket-authenticated and rejects the password login.
- **You actually want password login for root:** the plugin has to be switched.
- **MariaDB 10.4+:** `root` ships on `unix_socket` by default; the switch syntax differs slightly.

## Fix by Scenario

### Connecting from the shell after a fresh install

The account works exactly as designed. Connect as the OS `root` user and the socket check passes:

```bash
sudo mysql
```

No password prompt, no 1698. This is the intended path on Ubuntu 24.04 / MySQL 8.0 and 8.4 installs, and it's the one most tutorials skip.

### An application connects as root with a password

Don't repurpose `root` for this. `root@localhost` stays on socket auth; create a dedicated account with a real password and grant only the privileges the app needs. If the new account then fails with a database-level [ERROR 1044](/reference/mysql/error/1044-access-denied-for-user-to-database/), the grant is missing or scoped to the wrong host.

```sql
CREATE USER 'app_user'@'%' IDENTIFIED BY 'a-strong-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
```

Point the connection string at `app_user`. The error disappears because that account authenticates by password, not by OS identity.

### You want root itself to log in with a password

Connect with `sudo mysql`, then switch the plugin. On MySQL 8.0 / 8.4:

```sql
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'a-strong-password';
FLUSH PRIVILEGES;
```

Use `mysql_native_password` instead if an older client can't speak `caching_sha2_password`. After this, `mysql -u root -p` works, and `sudo mysql` will fail unless you pass `-p` (for example, `sudo mysql -p`).

### MariaDB 10.4 and later

MariaDB names the plugin `unix_socket`. Connect with `sudo mysql` and either switch to password auth or enable both methods:

```sql
ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('a-strong-password');
FLUSH PRIVILEGES;
```

## Prevention

- Check how an account authenticates before debugging passwords: `SELECT user, host, plugin FROM mysql.user WHERE user = 'root';`. A `plugin` of `auth_socket` or `unix_socket` means the password is irrelevant.
- Leave `root` on socket authentication and use `sudo mysql` for local admin work. It's harder to brute-force than a password.
- Give every application its own password-based account scoped to one database, never `root`.
- Match the authentication plugin to your client. New clients handle `caching_sha2_password`; older drivers may still need `mysql_native_password`.

> **Note:** Sharing one `root` login across a team is how credentials leak and changes go untracked. Bytebase puts a review-and-access layer in front of the database, so engineers connect through their own identity with scoped permissions instead of a shared superuser. See [Bytebase database permissions](https://www.bytebase.com/docs/security/database-permission/overview/).