Error Access denied for user 'root'@'localhost' adalah salah satu pesan error paling terkenal dan paling sering muncul di dunia MySQL. Entah kamu baru pertama kali menginstal MySQL di laptop, atau sudah berpengalaman tapi tiba-tiba terkunci keluar setelah upgrade, error ini hampir pasti pernah kamu temui. Artikel ini membongkar error tersebut dari akar masalahnya, memberikan solusi step-by-step yang bisa langsung kamu praktikkan, dan memastikan kamu tidak mengulangi kesalahan yang sama di masa depan.
Anatomi pesan error
Ketika MySQL menolak koneksi dari user root, pesan error yang muncul di layar terlihat seperti ini:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)Atau variasi lain yang menunjukkan bahwa kamu memang mengirimkan password tapi password-nya salah:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)Dalam bahasa Indonesia sederhana, pesan ini berarti: "Akses ditolak untuk pengguna 'root' yang mencoba terhubung dari komputer lokal (localhost)." MySQL secara eksplisit memberi tahu dua hal penting: siapa yang mencoba masuk (root), dan dari mana koneksi itu berasal (localhost). Bagian dalam kurung di akhir — (using password: NO) atau (using password: YES) — menunjukkan apakah kamu mengirimkan password saat mencoba koneksi atau tidak.
Kenapa error ini muncul? Secara fundamental, MySQL memiliki tabel privilege bernama mysql.user yang menyimpan seluruh informasi tentang siapa boleh masuk, dari mana, dan dengan kata sandi apa. Ketika sebuah koneksi masuk, MySQL akan mencocokkan kombinasi user dan host terhadap tabel tersebut. Jika tidak ada kecocokan, atau jika password yang dikirim tidak sesuai dengan hash yang tersimpan, MySQL langsung menolak koneksi sebelum kamu sempat menjalankan satu pun perintah SQL. Ini bukan masalah jaringan atau port — ini murni masalah autentikasi di level database.
Perbedaan antara (using password: NO) dan (using password: YES) sangat krusial untuk diagnosis. Jika kamu melihat (using password: NO), itu artinya klien MySQL yang kamu gunakan tidak mengirimkan password sama sekali — mungkin karena kamu lupa menambahkan flag -p, atau konfigurasi aplikasi kamu memang tidak mengisi field password. Sebaliknya, (using password: YES) berarti kamu mengirimkan password, tapi password tersebut salah atau tidak cocok dengan yang terdaftar di mysql.user.
Berikut contoh nyata ketika error ini muncul di berbagai konteks. Saat menjalankan klien MySQL dari terminal:
mysql -u root
# Output: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
Mysql -u root -p
# Kamu memasukkan password yang salah
# Output: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)Saat aplikasi PHP dengan PDO mencoba koneksi:
$conn = new PDO("mysql:host=localhost;dbname=testdb", "root", "password_salah");
// Fatal error: Uncaught PDOException: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES)Saat aplikasi Node.js menggunakan mysql2:
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password_salah',
database: 'testdb'
});
connection.connect((err) => {
// err.code === 'ER_ACCESS_DENIED_ERROR'
// err.sqlMessage === "Access denied for user 'root'@'localhost' (using password: YES)"
});Pemahaman terhadap anatomi error ini adalah langkah pertama yang paling penting. Tanpa memahami apa yang ditunjukkan oleh pesan error, kamu hanya akan menerka-nerka solusi tanpa arah.
Sumber masalah
Ada beberapa root cause yang mengakibatkan error ini, dan penting untuk mengidentifikasi mana yang sedang kamu alami sebelum melompat ke solusi. daftar penyebab dari yang paling sering terjadi hingga yang lebih jarang:
Password root yang salah atau terlupakan. Ini adalah penyebab paling umum. Kamu menginstal MySQL, menyetel password root saat instalasi, lalu beberapa minggu kemudian lupa apa password-nya. Atau mungkin kamu mengikuti tutorial yang menginstruksikan password tertentu, tapi instalasi kamu sudah memiliki password yang berbeda. Cara memastikan: jika kamu melihat
(using password: YES)dan kamu yakin user-nya benar, kemungkinan besar ini masalah password.User root tidak memiliki hak akses untuk host localhost. Di MySQL, user
root@localhostdanroot@127.0.0.1danroot@%adalah tiga entitas yang berbeda. Mungkin saja root hanya terdaftar untuk127.0.0.1atau%(semua host), tapi tidak untuklocalhost. Ini sering terjadi di MySQL 8.0 ke atas, di mana proses instalasi default membuat user root dengan plugin autentikasicaching_sha2_passworduntuk koneksi socket, tapi tidak untuk TCP localhost. Cara memastikan: jika kamu bisa connect denganmysql -u root -h 127.0.0.1 -ptapi gagal denganmysql -u root -h localhost -p, ini masalah host matching.Plugin autentikasi tidak kompatibel. MySQL 8.0 mengubah default authentication plugin dari
mysql_native_passwordmenjadicaching_sha2_password. Klien lama (versi PHP sebelum 7.4, library MySQL Connector lama) tidak mendukung plugin baru ini. Hasilnya, meskipun password benar, koneksi tetap ditolak karena klien tidak bisa menangani handshake autentikasi. Cara memastikan: jika kamu bisa login dari klien MySQL versi 8 tapi gagal dari aplikasi dengan library database lama, ini kemungkinan besar masalah plugin.File konfigurasi yang menimpa kredensial. MySQL membaca file opsi seperti
~/.my.cnf,/etc/mysql/my.cnf, atau~/.my.ini. Jika file-file ini mengandung entri user dan password yang salah, setiap kali kamu menjalankanmysqldari terminal, kredensial tersebut otomatis dipakai dan bisa menyebabkan access denied. Cara memastikan: jalankanmysql --defaults-file=/dev/null -u root -puntuk bypass semua file konfigurasi. Jika berhasil, berarti ada file konfigurasi yang mengganggu.Instalasi fresh tanpa inisialisasi yang benar. Pada beberapa distribusi Linux, setelah
apt install mysql-server, user root dikonfigurasi untuk menggunakanauth_socketplugin (Ubuntu/Debian) yang berarti root hanya bisa login dari proses sistem yang berjalan sebagai root (menggunakansudo mysql). Jika kamu mencobamysql -u root -ptanpa sudo, kamu akan langsung ditolak. Cara memastikan: jikasudo mysqlberhasil tapimysql -u root -pgagal, ini masalah auth_socket.
Setiap penyebab di atas membutuhkan pendekatan solusi yang berbeda. Di section berikutnya, kita akan membahas solusi step-by-step yang menyasar masing-masing root cause ini.
Solusi step-by-step
Langkah 1: Coba login dengan sudo (Linux)
Di banyak instalasi MySQL di Ubuntu/Debian, user root dikonfigurasi dengan auth_socket plugin. Kamu bisa masuk tanpa password asalkan kamu adalah user root di sistem operasi:
sudo mysqlJika berhasil, kamu akan masuk ke MySQL prompt:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql>Jika ini berhasil, masalah kamu adalah root cause nomor 5 (auth_socket). Langkah selanjutnya adalah mengubah plugin autentikasi root agar bisa login dengan password normal:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password_baru_kamu';
FLUSH PRIVILEGES;Verifikasi: keluar dari MySQL (exit), lalu coba:
mysql -u root -p
# Masukkan: password_baru_kamu
# Output yang diharapkan: Welcome to the MySQL monitor...Langkah 2: Start MySQL dalam safe mode (skip-grant-tables)
Jika langkah 1 tidak berhasil, kamu perlu melewati sistem privilege MySQL seluruhnya untuk bisa masuk dan memperbaiki tabel user. Ini dilakukan dengan menjalankan MySQL daemon tanpa memuat grant tables:
# Hentikan MySQL yang sedang berjalan
sudo systemctl stop mysql
# Start MySQL dalam safe mode
sudo mysqld_safe --skip-grant-tables --skip-networking &Flag --skip-grant-tables membuat MySQL mengabaikan seluruh tabel privilege, sehingga siapa saja bisa masuk tanpa password. Flag --skip-networking mematikan koneksi TCP/IP untuk mencegah orang lain masuk selagi server dalam kondisi tidak aman — hanya koneksi melalui Unix socket yang diperbolehkan, dan biasanya hanya dari localhost.
Sekarang kamu bisa masuk tanpa password:
mysql -u root
# Output: Welcome to the MySQL monitor...Setelah masuk, perbaiki password root:
-- Penting: FLUSH PRIVILEAGES diperlukan sebelum ALTER USER
-- karena kita skip-grant-tables
FLUSH PRIVILEGES;
-- Untuk MySQL 5.7 dan 8.0
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password_baru_kamu';
-- Alternatif untuk MySQL 5.7.5 dan sebelumnya
-- SET PASSWORD FOR 'root'@'localhost' = PASSWORD('password_baru_kamu');
FLUSH PRIVILEGES;Setelah selesai, kembalikan MySQL ke mode normal:
sudo systemctl stop mysql
sudo systemctl start mysqlVerifikasi:
mysql -u root -p
# Masukkan: password_baru_kamu
# Output: Welcome to the MySQL monitor...Langkah 3: Mengatasi masalah plugin autentikasi (caching_sha2_password)
Jika kamu sudah bisa login sebagai root dan masalahnya adalah aplikasi kamu yang gagal connect karena plugin autentikasi, solusinya adalah mengubah plugin untuk user yang bersangkutan:
-- Cek plugin autentikasi saat ini
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';Output yang mungkin kamu lihat:
+------+-----------+-----------------------+
| user | host | plugin |
+------+-----------+-----------------------+
| root | localhost | caching_sha2_password |
+------+-----------+-----------------------+Ubah ke mysql_native_password:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password_kamu';
FLUSH PRIVILEGES;Verifikasi: jalankan lagi query SELECT di atas dan pastikan plugin sudah berubah:
+------+-----------+-----------------------+
| user | host | plugin |
+------+-----------+-----------------------+
| root | localhost | mysql_native_password |
+------+-----------+-----------------------+Kemudian coba connect dari aplikasi kamu yang sebelumnya gagal.
Langkah 4: Periksa dan bersihkan file konfigurasi yang mengganggu
# Periksa file my.cnf di home directory
cat ~/.my.cnf
# Periksa file konfigurasi global
cat /etc/mysql/my.cnf
cat /etc/my.cnfJika kamu menemukan entri seperti ini:
[client]
user = root
password = password_lama_yang_salahKomentari atau hapus baris tersebut, lalu coba connect lagi secara eksplisit:
mysql -u root -pLangkah 5: Untuk Windows — gunakan MySQL Installer atau init file
Di Windows, langkah skip-grant-tables sedikit berbeda:
:: Hentikan service MySQL
net stop mysql
:: Edit file konfigurasi
:: Tambahkan baris berikut di bawah [mysqld] di file C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
:: skip-grant-tables
:: Start service lagi
net start mysql
:: Login tanpa password
mysql -u rootSetelah masuk, lakukan ALTER USER seperti di langkah 2, lalu hapus baris skip-grant-tables dari my.ini dan restart service.
Alternatif yang lebih rapi di Windows adalah menggunakan init file:
:: Buat file C:\mysql-init.txt dengan isi:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password_baru_kamu';
:: Hentikan MySQL
net stop mysql
:: Start MySQL dengan init file
mysqld --init-file=C:\\mysql-init.txt
:: Setelah berhasil, stop MySQL, hapus init file, dan start MySQL secara normal
net start mysqlFix permanen (bukan workaround)
Semua solusi di section sebelumnya bersifat reaktif — kamu sudah terkunci, lalu kamu memaksa masuk dan memperbaiki. Tapi jika kamu tidak mengubah konfigurasi dan kebiasan setup, error ini bisa kembali muncul di kemudian hari. langkah-langkah untuk memastikan error ini tidak pernah terulang.
Konfigurasi yang mencegah error kembali
Pertama, pastikan user root memiliki entri yang benar untuk semua metode koneksi yang kamu gunakan. Di MySQL, sangat disarankan untuk membuat entri eksplisit baik untuk socket connection maupun TCP connection:
-- Pastikan root@localhost ada dan menggunakan password yang kamu inginkan
CREATE USER IF NOT EXISTS 'root'@'localhost' IDENTIFIED BY 'password_kamu';
-- Jika kamu juga perlu koneksi via 127.0.0.1
CREATE USER IF NOT EXISTS 'root'@'127.0.0.1' IDENTIFIED BY 'password_kamu';
-- Berikan semua hak akses
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;Kedua, jangan pernah menggunakan user root untuk aplikasi. Ini bukan hanya best practice keamanan, tapi juga mencegah kamu lupa password root karena kamu jarang menggunakannya. Buat user terpisah untuk setiap aplikasi:
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'strong_app_password';
CREATE USER 'app_user'@'%' IDENTIFIED BY 'strong_app_password';
-- Berikan hak akses hanya ke database yang diperlukan
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER
ON aplikasi_db.* TO 'app_user'@'localhost';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER
ON aplikasi_db.* TO 'app_user'@'%';
FLUSH PRIVILEGES;Ketiga, atur default_authentication_plugin di file konfigurasi MySQL agar konsisten dengan klien yang kamu gunakan. Di MySQL 8.0, tambahkan baris berikut di my.cnf (Linux) atau my.ini (Windows):
[mysqld]
default_authentication_plugin=mysql_native_passwordIni memastikan setiap user baru yang dibuat akan menggunakan mysql_native_password secara default, yang kompatibel dengan hampir semua klien dan library database yang ada saat ini. Restart MySQL setelah mengubah konfigurasi ini:
# Linux
sudo systemctl restart mysql
# Windows
net stop mysql
net start mysqlPerbedaan antar sistem operasi
Di Ubuntu/Debian, paket MySQL dari repositori default mengkonfigurasi root dengan auth_socket plugin. Ini artinya mysql -u root -p tidak akan pernah berhasil kecuali kamu mengubahnya. Fix permanen di Ubuntu adalah mengubah plugin tersebut segera setelah instalasi:
sudo mysql
# Di dalam MySQL prompt:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password_kamu';
FLUSH PRIVILEGES;
exitDi CentOS/RHEL/Fedora, instalasi MySQL melalui yum/dnf biasanya mengenerate temporary password root yang ditampilkan di log. Cek log tersebut setelah instalasi:
sudo grep 'temporary password' /var/log/mysqld.log
# Output: 2024-01-15T10:23:45.123456Z 1 [Note] A temporary password is generated for root@localhost: Ab3#xY9!kLmGunakan password sementara tersebut untuk login, lalu MySQL akan memaksamu mengubah password:
mysql -u root -p
# Masukkan temporary password
# Kemudian:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password_baru_kamu';Di Windows, MySQL Installer biasanya menyediakan dialog untuk menyetel password root selama instalasi. Pastikan kamu mencatat password tersebut. Jika kamu menggunakan MySQL Installer, kamu juga bisa membuka aplikasi tersebut kembali, pergi ke Reconfigure, dan menyetel ulang password root tanpa perlu skip-grant-tables. Lokasi konfigurasi di Windows biasanya berada di C:\ProgramData\MySQL\MySQL Server 8.0\my.ini — perhatikan bahwa ini di ProgramData, bukan Program Files, dan folder ini bersifat hidden secara default.
Sebagai best practice lintas platform, selalu simpan kredensial database di environment variable atau di file .env yang tidak masuk ke version control, bukan di-hardcode di source code:
# .env file (tambahkan ke .gitignore!)
DB_HOST=localhost
DB_USER=app_user
DB_PASS=strong_app_password
DB_NAME=aplikasi_db# Python dengan python-dotenv
import os
from dotenv import load_dotenv
load_dotenv()
DATABASE_URL = f"mysql://{os.getenv('DB_USER')}:{os.getenv('DB_PASS')}@{os.getenv('DB_HOST')}/{os.getenv('DB_NAME')}"Dengan pendekatan ini, kamu tidak perlu menyentuh kredensial root di level aplikasi, dan jika password perlu diubah, kamu hanya mengubah file .env tanpa mengubah kode.
Langkah lanjutan
Jika semua solusi di atas sudah kamu coba tapi error masih muncul, ada beberapa kemungkinan yang lebih dalam yang perlu kamu investigasi.
Baca log MySQL
Log MySQL adalah sumber informasi paling kaya ketika solusi standar tidak work. Lokasi log bervariasi tergantung OS dan konfigurasi:
# Ubuntu/Debian — default location
sudo tail -n 100 /var/log/mysql/error.log
# CentOS/RHEL
sudo tail -n 100 /var/log/mysqld.log
# macOS (Homebrew)
tail -n 100 /usr/local/var/mysql/*.err
# Windows — lihat di Event Viewer atau
type "C:\ProgramData\MySQL\MySQL Server 8.0\data\<hostname>.err"Di log, cari pesan yang berhubungan dengan waktu kamu mencoba koneksi. Kamu mungkin menemukan pesan seperti:
2024-01-15T10:30:00.000000Z 6 [Note] Access denied for user 'root'@'localhost' (using password: YES)
2024-01-15T10:30:00.000000Z 6 [Note] mysql_native_password: authentication failed for 'root'@'localhost'Atau pesan yang menunjukkan masalah lebih fundamental:
2024-01-15T10:30:00.000000Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't existJika kamu melihat error tentang privilege tables yang tidak bisa dibuka, ini artinya database sistem mysql itu sendiri bermasalah — mungkin corrupt atau tidak terinisialisasi. Dalam kasus ini, kamu perlu menjalankan reinitialisasi:
sudo systemctl stop mysql
sudo mysqld --initialize --user=mysql --datadir=/var/lib/mysql
sudo systemctl start mysqlPerhatikan bahwa --initialize akan menghapus seluruh data yang ada di datadir. Gunakan hanya sebagai upaya terakhir.
Cek apakah MySQL berjalan dan mendengarkan di port yang benar
Kadang masalahnya bukan autentikasi, tapi MySQL tidak berjalan atau mendengarkan di port yang kamu kira:
# Cek status service
sudo systemctl status mysql
# Cek port yang didengarkan
sudo ss -tlnp | grep 3306
# Atau
sudo netstat -tlnp | grep 3306Output yang diharapkan:
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=1234,fd=15))Jika MySQL tidak mendengarkan sama sekali, ada masalah startup. Cek log error untuk menemukan penyebabnya. Jika MySQL mendengarkan di 127.0.0.1:3306 tapi kamu mencoba connect via Unix socket dengan localhost, coba secara eksplisit menggunakan TCP:
mysql -u root -h 127.0.0.1 -P 3306 -pCek versi klien versus versi server
Versi mismatch antara klien MySQL dan server MySQL bisa menyebabkan masalah autentikasi yang sulit didiagnosis:
# Cek versi klien
mysql --version
# Cek versi server (setelah berhasil masuk)
mysql> SELECT VERSION();Jika klien kamu versi 5.x dan server versi 8.0, klien mungkin tidak mendukung caching_sha2_password. Solusinya: upgrade klien, atau ubah plugin autentikasi user ke mysql_native_password seperti yang sudah dibahas.
Gunakan mysqladmin untuk verifikasi koneksi
mysqladmin adalah tool ringan yang bisa membantu verifikasi:
mysqladmin -u root -p ping
# Jika password benar:
# Output: mysqld is alive
# Jika password salah:
# Output: mysqladmin: connect to server at 'localhost' failed
# error: 'Access denied for user 'root'@'localhost' (using password: YES)'Sumber resmi untuk deep-dive
Jika kamu sudah exhausted semua langkah di atas dan masih bermasalah, referensi berikut adalah sumber otoritatif yang bisa kamu pelajari lebih lanjut:
MySQL 8.0 Reference Manual — Section 6.2 "Access Control and Account Management": Ini menjelaskan secara lengkap bagaimana MySQL mengevaluasi kredensial dan menentukan apakah sebuah koneksi diperbolehkan. URL:
https://dev.mysql.com/doc/refman/8.0/en/access-control.htmlMySQL 8.0 Reference Manual — Section 6.2.9 "Troubleshooting Problems Connecting to MySQL": Bagian ini secara spesifik membahas error 1045 dan berbagai skenario yang menyebabkannya. URL:
https://dev.mysql.com/doc/refman/8.0/en/problems-connecting.htmlMySQL 8.0 Reference Manual — Section 6.4.1 "Authentication Plugins": Menjelaskan perbedaan antara
mysql_native_password,caching_sha2_password, danauth_socketsecara mendetail. URL:https://dev.mysql.com/doc/refman/8.0/en/authentication-plugins.htmlMySQL System Variables —
default_authentication_plugin: Dokumentasi tentang konfigurasi global yang menentukan plugin autentikasi default. URL:https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_pluginStack Overflow Tag [mysql] + "access denied": Ribuan pertanyaan dan jawaban dari kasus nyata yang mungkin spesifik terhadap environment kamu. URL:
https://stackoverflow.com/questions/tagged/mysql+access-denied
Error Access denied for user 'root'@'localhost' terasa frustasi saat pertama kali muncul, tapi dengan memahami anatomi error-nya, mengidentifikasi root cause yang tepat, dan menerapkan fix permanen, kamu tidak hanya menyelesaikan masalah saat ini — kamu juga membangun fondasi yang kuat sehingga error ini tidak pernah menghantui kamu lagi.