Pada episode ini kita akan membedah request yang gagal: membaca log verbose dan trace lengkap, menganalisis timing tiap fase koneksi, menerjemahkan exit code curl, serta memetakan solusi untuk error DNS, koneksi ditolak, timeout, sertifikat SSL, dan proxy.

Di episode 17 kalian sudah melihat bagaimana curl menjadi tulang punggung banyak tool testing API dan ekosistem otomasi — alat yang tampak "tidak terlihat" sampai tiba-tiba sebuah request gagal di server produksi. Nah, saat itulah debugging menjadi pembeda antara praktisi yang menebak-nebak dan praktisi yang membaca bukti.
Masalahnya, curl itu pendiam. Ketika request gagal, ia hanya keluar dengan sebuah kode angka dan mungkin satu baris error — tanpa penjelasan di mana tepatnya hal itu terjadi. Seperti mobil yang mogok di tengah jalan tanpa lampu indikator: kalian tahu ada yang salah, tapi tidak tahu di sistem mana. Episode 18 ini akan memasang "dashboard lengkap" pada curl: log verbose, trace byte-demi-byte, pengukuran timing tiap fase, serta kamus exit code dan error yang paling sering muncul di dunia nyata.
-v: Melihat Proses dari DalamOpsi -v (verbose) membuat curl membuka pintu mesin dan menceritakan setiap langkah yang ia lakukan. Ini opsi debugging pertama yang harus kalian nyalakan setiap kali sesuatu terasa aneh.
curl -v https://api.example.com/healthOutputnya panjang, tapi informasinya terstruktur. Berikut contoh bentuknya:
* Trying 104.18.20.123:443...
* Connected to api.example.com (104.18.20.123) port 443
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
> GET /health HTTP/2
> Host: api.example.com
> User-Agent: curl/8.x.x
> Accept: */*
>
< HTTP/2 200
< content-type: application/json
<
{"status":"ok"}Kunci membacanya ada di tiga awalan baris:
* adalah informasi internal curl: alamat yang disambung, fase TLS, hingga resolusi DNS.> adalah request yang dikirim curl ke server.< adalah respons yang diterima curl dari server.Dengan pola ini, kalian langsung tahu titik kegagalan: jika tidak ada baris * Connected, koneksi TCP-nya sendiri yang gagal. Jika baris TLS tidak muncul, masalahnya ada di handshake. Jika header > sudah terkirim tapi respons < tidak pernah datang, kemungkinan besar server yang bermasalah — bukan jaringan.
Tip
Saat memakai -v, tambahkan -sS untuk meredam progress meter tapi tetap menampilkan error: curl -sS -v https://api.example.com/health. Output jadi bersih di layar tanpa baris progress yang menggulung, tanpa menghilangkan pesan error yang penting.
--trace dan --trace-ascii-v menampilkan ringkasan, tapi kadang kalian butuh rekaman lengkap — seperti black box pesawat yang merekam seluruh percakapan. Opsi --trace-ascii menyimpan seluruh data yang dikirim dan diterima, termasuk isi header, body, dan detail handshake yang tidak terlihat di -v.
curl --trace-ascii trace.txt https://api.example.com/healthVersi file sangat berguna untuk request yang panjang — hasilnya bisa dibuka di editor dan dicari baris yang mencurigakan. Awalan - pada argumen berarti "tulis ke terminal". Jika kalian butuh melihat byte mentah, termasuk data heksadesimal penuh, gunakan --trace — versi ini menulis seluruh data dalam format heksadesimal, berguna saat debugging masalah encoding atau protokol level rendah.
-wError yang jelas memang membantu, tapi kasus tersulit biasanya soal performa: request sukses, tapi lambat. Di sinilah kalian butuh stopwatch. Opsi -w (write-out) sudah kalian kenal di episode 6 untuk mencetak status code; sekarang kita pakai untuk mengukur tiap fase koneksi.
curl -s -o /dev/null -w "DNS: %{time_namelookup}s\nTCP: %{time_connect}s\nTLS: %{time_appconnect}s\nByte pertama: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
https://api.example.com/health-o /dev/null membuang body agar yang terukur murni waktu, bukan waktu render terminal. Setiap variabel mengukur fase yang berbeda:
| Variabel | Fase yang diukur |
|---|---|
time_namelookup | Resolusi DNS: mengubah nama jadi alamat IP |
time_connect | Handshake TCP: pembentukan koneksi |
time_appconnect | Handshake TLS: negosiasi enkripsi selesai |
time_starttransfer | Waktu sampai byte pertama respons tiba |
time_total | Total keseluruhan transfer |
Perhatikan polanya: jika time_connect tinggi, masalahnya di jaringan. Jika time_connect rendah tapi time_appconnect tinggi, kemungkinan besar di TLS atau CA. Jika semuanya cepat tapi time_starttransfer melonjak, berarti server lambat merespons — atau koneksi hang di sisi server. Membaca angka-angka ini seperti membaca EKG: setiap lonjakan menunjuk ke organ yang berbeda.
Ketika curl selesai, ia keluar dengan sebuah exit code. Angka ini adalah bahasa yang dipahami oleh skrip — bukan sekadar "gagal", tapi kategori gagalnya. Di dalam skrip, kalian bisa memeriksanya secara eksplisit:
curl -sS https://api.example.com/health
echo "exit code: $?"| Kode | Arti | Umumnya karena |
|---|---|---|
| 0 | Sukses | - |
| 6 | Could not resolve host | DNS gagal atau typo nama host |
| 7 | Failed to connect | Port tertutup, service mati, atau ditolak |
| 22 | HTTP page not retrieved | Kode status >= 400 saat memakai --fail |
| 28 | Operation timeout | Koneksi atau transfer melampaui batas waktu |
| 35 | SSL connect error | Gagal saat handshake TLS |
| 60 | SSL certificate problem | Sertifikat tidak valid atau CA tidak dipercaya |
| 77 | CA cert tidak dapat dibaca | Berkas bundle CA hilang atau korup |
Tip
Hafalkan tiga kode paling penting: 6 (DNS), 7 (koneksi), dan 28 (timeout) — ini mencakup mayoritas kegagalan jaringan di dunia nyata. Untuk skrip, gabungkan dengan --fail-with-body agar curl juga keluar non-zero ketika server mengembalikan status 4xx/5xx — bukan hanya ketika koneksi-nya yang gagal.
Sekarang kita petakan error yang paling sering muncul ke akar masalahnya. Ingat prinsip dari episode 9: jangan menebak, lihat bukti.
Could not resolve hostError ini muncul saat curl tidak bisa mengubah nama host menjadi alamat IP. Penyebab paling umum: salah ketik nama, DNS server tidak bisa menjawab, atau koneksi ke DNS server sendiri yang terputus.
dig +short api.example.comJika dig kosong atau error, masalahnya di DNS — bukan di curl. Coba nama host lain, atau ganti DNS server di sistem. Jika dig berhasil tapi curl tetap gagal, periksa apakah ada proxy yang mengganggu (lihat bagian proxy di bawah).
Connection refusedPesan ini berarti server menolak koneksi TCP — biasanya karena tidak ada service yang mendengarkan di port tersebut. Bisa juga karena firewall menolak secara eksplisit, atau service-nya memang belum aktif.
ss -tlnp | grep ':443'Jika tidak ada baris LISTEN untuk port 443, maka aplikasinya tidak berjalan — restart service-nya. Jika ada, periksa apakah curl menuju host dan port yang benar; kombinasi host benar tapi port salah adalah penyebab paling membingungkan.
Timeout berarti curl menyerah menunggu jawaban. Berbeda dengan Connection refused (server menolak cepat), timeout terjadi ketika paket dibiarkan menggantung — umumnya karena firewall membuang paket diam-diam (silent drop) atau server kewalahan. Jangan langsung menaikkan batas waktu tanpa bukti; ukur dulu dengan -w untuk melihat di fase mana kemacetan terjadi.
SSL certificate problemError ini muncul saat verifikasi TLS gagal: sertifikat kedaluwarsa, hostname tidak cocok, atau rantai CA tidak dikenal oleh sistem. Debugging-nya bukan menonaktifkan verifikasi, melainkan memeriksa sertifikat server:
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
| openssl x509 -noout -datesBaris notBefore dan notAfter menunjukkan masa berlaku sertifikat. Jika sudah lewat notAfter, itu sebabnya verifikasi gagal — dan solusinya ada di pihak pemilik server, bukan di sisi kalian.
Warning
Jangan pernah menyelesaikan SSL certificate problem dengan flag -k atau --insecure — itu mematikan verifikasi sertifikat dan membuat koneksi bisa disadap oleh siapa pun di jalur. Cara yang benar adalah memperbaiki penyebabnya: perbarui CA bundle, perbaiki tanggal sistem, atau hubungi pemilik server. Kita akan membahas kebijakan TLS yang benar secara menyeluruh di episode 21.
Error yang paling licik datang dari proxy yang ikut campur. Gejalanya: curl gagal di lingkungan tertentu (CI, kantor, VPN) padahal berhasil di laptop. curl membaca variabel environment seperti http_proxy, https_proxy, dan NO_PROXY secara otomatis. Jika variabel itu salah set, semua request kalian menabrak proxy yang tidak ada.
env | grep -i proxycurl --noproxy '*' https://api.example.com/healthJika --noproxy '*' berhasil, berarti lingkungan kalian menyuntikkan proxy. Periksa isi http_proxy dan https_proxy, lalu perbaiki atau set NO_PROXY untuk host internal. Sebaliknya, jika request justru harus lewat proxy, gunakan -x secara eksplisit — dan perhatikan bahwa Could not resolve proxy berarti nama host proxy-nya sendiri tidak ter-resolve, masalah DNS lagi.
Kunci debugging curl adalah membangun tangga yang konsisten, dari yang paling cepat ke yang paling dalam:
-v — di fase mana log berhenti?-w — kuantifikasi timing tiap fase.--trace-ascii — buka detail byte-demi-byte.Urutan ini mencegah kalian membuang waktu: jika gagal di DNS, jangan buka-buka sertifikat. Jika gagal di TLS, jangan ubah-ubah proxy. Setiap lapisan log memberi petunjuk ke lapisan berikutnya.
Episode 18 membekali kalian dengan perangkat diagnostik yang lengkap: membaca log verbose dengan awalan *, >, dan <, merekam trace lengkap dengan --trace-ascii, mengukur timing tiap fase koneksi dengan -w, menerjemahkan exit code curl dari DNS hingga sertifikat, serta memetakan error umum beserta akar masalahnya.
Yang paling berharga bukan alatnya, melainkan kebiasaannya: debugging bukan menebak, tapi membaca bukti secara berurutan. Mulailah dari exit code, turun ke verbose, kuantifikasi dengan timing, dan jika perlu buka trace-nya.
Di episode 19 berikutnya kita akan berpindah dari mode perbaikan ke mode pemanfaatan: fitur stabil terbaru curl 8.x — dari --json dan --oauth2-bearer, WebSocket dan HTTP/3, hingga transfer paralel dan --libcurl. Sampai jumpa!