Aplikasi gagal menyambung ke MongoDB selalu terdeteksi pada menit pertama: log dipenuhi pesan galat yang sama berulang-ulang, dan semua fitur yang menyentuh database ikut berhenti. Pesan seperti MongoNetworkError: connect ECONNREFUSED terasa seperti teka-teki bila kita belum tahu cara membacanya, padahal hampir semua kasus berasal dari segelintir penyebab: server tidak berjalan, port atau URI salah tulis, DNS gagal, atau jaringan yang memblokir. Chapter ini mereproduksi tiap galat itu di mesin latihan dengan cara yang aman, membedah artinya, lalu menutup dengan tabel rujukan gejala-penyebab-solusi.
Peta materi Chapter ini:
- Tiga kelas galat koneksi dan lapisan tempatnya terjadi.
- Mereproduksi
ECONNREFUSED, lalu memverifikasi port dari shell OS dengancurl. - Server selection timeout, kegagalan DNS SRV, dan URI yang salah tulis.
- Peran
bindIpdan firewall, plus verifikasi koneksi dari dalam mongosh.
Membaca Kelas Galat #
Sebelum menyentuh server, baca dulu nama kelas galatnya. mongosh dan semua driver resmi memakai penamaan yang konsisten, dan nama itu langsung menunjuk lapisan yang bermasalah:
| Kelas galat | Lapisan | Pertanyaan yang dijawab |
|---|---|---|
MongoNetworkError | Transport TCP/OS | Koneksi ke satu host tertentu gagal dibangun? |
MongoServerSelectionError | Driver/topologi | Tidak ada server yang memenuhi syarat dalam batas waktu? |
MongoParseError, MongoRuntimeError | Connection string | URI-nya sendiri sudah valid sebelum mencoba tersambung? |
Aturan bacanya: galat parse diperbaiki di URI, galat network diperiksa di level sistem operasi, galat selection berarti beberapa host bermasalah sekaligus atau syarat koneksi (read preference, TLS) tidak terpenuhi. Pesan lengkap di bawah nama kelas menentukan langkah berikutnya — kita bedah satu per satu.
Port yang Mati: ECONNREFUSED #
Bentuk paling klasik: mongod tidak berjalan, atau berjalan di port lain. Kita reproduksi dengan mengarahkan mongosh ke port yang pasti kosong:
mongosh --quiet --port 28099 --eval 'db.adminCommand({ping:1})'Output yang Dihasilkan:
MongoNetworkError: connect ECONNREFUSED 127.0.0.1:28099Sistem operasi menjawab dengan tegas: tidak ada proses yang mendengarkan port 28099, sehingga kernel mengirim balasan penolakan dan mongosh melaporkannya sebagai ECONNREFUSED. Galat ini justru kabar baik — host jelas terjangkau dan jawabannya pasti, jadi tersisa dua tersangka: mongod mati atau port salah tulis. Sebelum menyalakan ulang apa pun, verifikasi port dari shell OS:
curl -v telnet://127.0.0.1:28099Output yang Dihasilkan:
* Trying 127.0.0.1:28099...
* connect to 127.0.0.1 port 28099 from 127.0.0.1 port 48148 failed: Connection refused
* Failed to connect to 127.0.0.1 port 28099 after 0 ms: Could not connect to server
* closing connection #0Bandingkan dengan port yang hidup — opsi -m 2 memberi batas dua detik agar curl berhenti sendiri:
curl -v -m 2 telnet://127.0.0.1:27017Output yang Dihasilkan:
* Trying 127.0.0.1:27017...
* Connected to 127.0.0.1 (127.0.0.1) port 27017
* Time-out
* shutting down connection #0Dua hal perlu dicermati. Angka 48148 adalah port sementara milik curl sendiri — nilainya berubah tiap eksekusi dan bukan bagian dari diagnosis. Baris Time-out pada ujian kedua juga bukan kegagalan: mode telnet menunggu data setelah tersambung, sementara mongod tidak mengirim apa pun sebelum klien berbicara; baris Connected to ... adalah bukti port terbuka. Kode exit-nya pun berbeda: 7 (gagal tersambung) versus 28 (berhenti karena batas waktu).
Timeout, DNS SRV, dan URI yang Salah #
Kebalikan dari ECONNREFUSED adalah host yang tidak menjawab sama sekali. Kita reproduksi dengan IP pribadi yang tidak ter-route dan batas waktu pemilihan server yang pendek:
mongosh --quiet "mongodb://10.255.255.1:27017/?directConnection=true&serverSelectionTimeoutMS=3000" --eval 'db.adminCommand({ping:1})'Output yang Dihasilkan:
MongoServerSelectionError: Server selection timed out after 3000 msDriver mencoba membangun koneksi TCP dan tidak menerima jawaban apa pun — bukan penolakan — sampai batas serverSelectionTimeoutMS (bawaan 30 detik) terlampaui. Penyebab umumnya: host mati total, firewall yang membungkam paket, atau jalur VPN yang putus. Firewall yang menolak menghasilkan ECONNREFUSED yang cepat; firewall yang membungkam menghasilkan timeout yang lambat.
Dua galat berikutnya terjadi bahkan sebelum koneksi dicoba. Skema mongodb+srv memicu pencarian DNS record SRV, dan bila domainnya tidak ada:
mongosh --quiet "mongodb+srv://cluster0.example.com" --eval 'db.adminCommand({ping:1})'Output yang Dihasilkan:
Error: querySrv ENOTFOUND _mongodb._tcp.cluster0.example.comDriver mencari record _mongodb._tcp.cluster0.example.com dan DNS menjawab “tidak ada” (ENOTFOUND). Perbaikannya ada di URI atau di DNS-nya: pastikan nama cluster ditulis lengkap, resolver berfungsi, dan record SRV memang sudah dibuat. Terakhir, opsi URI yang salah tulis:
mongosh --quiet "mongodb://127.0.0.1:27017/?foo=bar" --eval 'db.adminCommand({ping:1})'Output yang Dihasilkan:
MongoParseError: option foo is not supportedGalat parse murni soal teks URI dan tidak pernah menyentuh jaringan — port yang bukan angka atau skema yang salah menghasilkan keluarga galat serupa (Unable to parse ... with URL). Perbaikannya cepat: koreksi URI, jangan menyalakan ulang server.
bindIp, Firewall, dan Verifikasi Koneksi #
Satu penyebab yang sering terlewat: mongod berjalan sehat tetapi hanya mendengarkan satu interface. Konfigurasi bawaan (dan server latihan kita) memuat bindIp: 127.0.0.1, artinya koneksi hanya diterima dari mesin yang sama; koneksi dari komputer lain akan timeout atau ditolak tergantung firewall. Memperluas akses berarti mengubah bindIp, membuka port di firewall, dan menyalakan TLS serta authentication — dibahas di Section Keamanan.
Setelah koneksi berhasil, dua pemeriksaan ringkas memverifikasi bahwa sasarannya memang benar. Perintah hello mengonfirmasi topologi dari sudut pandang klien:
use latihan_trouble
const hello = db.hello()
print("setName: " + hello.setName)
print("primary: " + hello.primary)
print("isWritablePrimary: " + hello.isWritablePrimary)Output yang Dihasilkan:
switched to db latihan_trouble
setName: rs0
primary: 127.0.0.1:27017
isWritablePrimary: trueBaris demi baris: setName memastikan replica set yang dituju sudah benar, primary menunjuk anggota penerima write, dan isWritablePrimary: true menegaskan node ini boleh menerima write. Untuk gejala “kadang connect, kadang gagal”, penghitung koneksi server adalah tempat lihat berikutnya:
db.adminCommand({ ping: 1 }).ok
db.serverStatus().connectionsOutput yang Dihasilkan:
1
{
current: 5,
available: 404,
totalCreated: 12245,
rejected: 0,
active: 1,
queuedForEstablishment: 0,
establishmentRateLimit: { rejected: 0, exempted: 0, interruptedDueToClientDisconnect: 0 },
threaded: 5,
exhaustIsMaster: Long('0'),
exhaustHello: Long('0'),
awaitingTopologyChanges: Long('0'),
loadBalanced: 0,
priority: 0
}Angka pasti berbeda tiap eksekusi, tetapi relasinya tetap: current koneksi terbuka saat ini, available sisa kapasitas, totalCreated akumulasi sejak server menyala. Bila current terus merambat naik tanpa turun, aplikasi membuka koneksi tanpa menutupnya — arah perbaikannya ada di connection pool aplikasi (Chapter Connection Pooling).
Tabel Rujukan Cepat #
| Gejala | Penyebab umum | Solusi pertama |
|---|---|---|
connect ECONNREFUSED | mongod mati atau port salah | Periksa proses dan port; uji dengan curl -v telnet://host:port |
Server selection timed out | Host tidak menjawab; firewall membungkam paket | Uji jalur jaringan/VPN; turunkan serverSelectionTimeoutMS agar gagal cepat |
querySrv ENOTFOUND | Domain atau record SRV tidak ada | Koreksi nama cluster di URI; periksa resolver DNS |
option ... is not supported / Unable to parse ... with URL | Opsi, port, atau skema URI salah tulis | Koreksi format mongodb://host:port dan daftar opsinya |
| Koneksi dari jauh selalu timeout | bindIp hanya 127.0.0.1 | Ubah bindIp; buka port firewall dengan TLS dan authentication aktif |
current merangkak mendekati available | Aplikasi membocorkan koneksi | Audit connection pool; pastikan klien menutup koneksi |
Rangkuman #
- Nama kelas galat menunjuk lapisannya: parse berarti URI, network berarti transport, selection berarti topologi.
ECONNREFUSEDadalah penolakan cepat dari OS — periksa proses dan port; timeout berarti tidak ada jawaban — periksa host, firewall, atau jalur jaringan.curl -v telnet://host:portmemverifikasi port tanpa kredensial dalam satu baris.- Skema
mongodb+srvbergantung pada record SRV;ENOTFOUNDberarti masalah selesai sebelum koneksi dimulai. - Setelah terhubung:
hello()memverifikasi topologi,pingmemverifikasi respons,serverStatus().connectionsmengawasi kelebihan koneksi.