unable to verify the first certificate. Sertifikatnya belum kedaluwarsa dan nama domainnya cocok, tapi koneksinya tetap ditolak. Penyebab yang paling sering bukan sertifikatnya, melainkan intermediate certificate yang tidak ikut dikirim oleh server.
Asumsi bahwa browser desktop adalah alat uji yang cukup kelihatannya masuk akal, karena browser adalah client yang paling sering kita pakai. Masalahnya, browser modern justru termasuk client yang paling toleran terhadap konfigurasi yang kurang lengkap.
Kenapa Chrome tetap menampilkan gembok
Client yang tidak menambal chain sendiri
unable to verify the first certificate. curl dengan backend OpenSSL umumnya menampilkan SSL certificate problem: unable to get local issuer certificate. Java biasanya melempar PKIX path building failed.
Dampak di production sering lebih terasa daripada yang terlihat di awal. Halaman web normal, jadi tidak ada yang curiga. Sementara itu notifikasi payment gateway tidak sampai, aplikasi mobile gagal login, dan integrasi API antar server putus. Di meja support, kalimat yang sering muncul adalah: di browser aman kok, berarti masalahnya di aplikasi. Padahal hal pertama yang layak dicek justru chain yang dikirim server.
Cara mengecek chain dengan openssl s_client
BASH
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null-servername mengirim SNI, yaitu nama host yang diminta client. Opsi ini penting di server yang melayani banyak domain di satu IP, supaya kamu melihat sertifikat untuk domain yang benar. -showcerts menampilkan semua sertifikat yang dikirim server, dan </dev/null membuat perintah langsung selesai setelah handshake.
Bagian yang perlu dibaca adalah Certificate chain dan baris Verify return code di bagian bawah. Ini contoh format output untuk chain yang tidak lengkap:
TEXT
Certificate chain
0 s:CN = example.com
i:C = XX, O = Contoh CA, CN = Contoh Intermediate CA
---
...
Verify return code: 21 (unable to verify the first certificate)s: adalah subject, yaitu sertifikat milik siapa. Baris i: adalah issuer, yaitu siapa yang menandatanganinya. Pada contoh ini hanya ada entri nomor 0, yaitu leaf. Issuer-nya adalah sebuah intermediate, tapi intermediate itu tidak muncul sebagai entri nomor 1. Itu tanda chain-nya bolong.
Pada chain yang lengkap, entri nomor 1 punya subject yang sama persis dengan issuer entri nomor 0, dan Verify return code bernilai 0 (ok). Perlu dicatat, s_client memakai trust store default sesuai cara OpenSSL di-build. Kalau semua domain menghasilkan error verifikasi, termasuk domain yang jelas sehat, kemungkinan trust store-nya yang tidak ditemukan. Di kasus seperti itu kamu bisa menunjuk file CA bundle sistem dengan opsi -CAfile, dan lokasinya berbeda per distro.
Untuk cek cepat dari sisi client, curl -sv https://example.com -o /dev/null juga cukup. Kalau curl gagal di verifikasi sementara browser lancar, hampir pasti masalahnya ada di chain.
Memasang intermediate yang benar
BASH
# Issuer milik sertifikat domain harus sama dengan subject intermediate
openssl x509 -in domain.crt -noout -subject -issuer
openssl x509 -in intermediate.crt -noout -subject
# Gabungkan dengan urutan leaf dulu, lalu intermediate
cat domain.crt intermediate.crt > fullchain.crt-----END CERTIFICATE----- dan -----BEGIN CERTIFICATE----- tidak menempel di satu baris. Hal ini bisa terjadi kalau file pertama tidak diakhiri newline.
Cara pasangnya tergantung web server dan panel yang dipakai:
- cPanel/WHM: form instalasi SSL biasanya punya kolom terpisah untuk CA bundle. Kalau kolom itu dikosongkan, server hanya mengirim leaf. Nama kolomnya bisa sedikit berbeda antar versi.
- Nginx: tidak punya direktif khusus untuk chain.
ssl_certificateharus menunjuk ke file gabungan, misalnyassl_certificate /path/ke/fullchain.crt;. Jalankannginx -tsebelum reload. - Apache: mulai 2.4.8,
SSLCertificateFilebisa berisi leaf beserta chain. Konfigurasi lama memakaiSSLCertificateChainFileyang terpisah. Cek konfigurasi denganapachectl configtest. - Certbot: Certbot membuat
cert.pem(leaf saja) danfullchain.pem(leaf beserta intermediate). Kesalahan yang sering terjadi adalah memakaicert.pemdi konfigurasi web server, padahal seharusnyafullchain.pem. - LiteSpeed: pengaturan chain tergantung versi dan apakah dikelola lewat panel atau WebAdmin. Cek dokumentasi untuk setup yang kamu pakai.
0 (ok).
