Gejala yang biasanya terlihat duluan
Authentication-Results pada email yang diterima. Kalau masalahnya ada di record DNS, keterangannya biasanya mengarah ke public key. Contohnya dkim=neutral (invalid public key), dkim=permerror (key syntax error), atau no key for signature. Kata-kata persisnya berbeda antar penerima, jadi jangan terpaku pada string tertentu. Kalau belum terbiasa membaca header ini, ada penjelasannya di artikel soal membaca header Authentication-Results.
Bedakan dengan pesan seperti body hash did not verify. Pesan itu berarti key berhasil dibaca dan dipakai, tapi isi email berubah setelah ditandatangani, misalnya karena footer tambahan, mailing list, atau filter antivirus. Itu bukan masalah DNS. Kalau kamu melihat pesan ini, berhenti di sini dan cari di jalur pengiriman, bukan di record TXT.
Di meja support, laporan seperti ini biasanya datang sebagai "DKIM sudah aktif tapi tetap gagal". Pelanggan sudah merasa copy-paste dengan benar, jadi pengecekan perlu dimulai dari apa yang benar-benar disajikan DNS, bukan dari apa yang terlihat di form panel.
Kenapa key 2048-bit harus dipecah
p=-nya sekitar 216 karakter base64, jadi seluruh record bisa disimpan sebagai satu string. Key 2048-bit nilai p=-nya sekitar 392 karakter. Ditambah v=DKIM1; k=rsa; di depannya, totalnya jauh di atas 255. Mau tidak mau, record itu harus disimpan sebagai beberapa string di dalam satu record TXT yang sama.
Spesifikasi DKIM (RFC 6376) mengatur bahwa verifier menggabungkan semua string dalam satu record TXT tanpa menambahkan spasi atau karakter apa pun di antaranya. Jadi pemecahan itu sendiri tidak masalah, selama dua syarat terpenuhi. Pertama, semua potongan berada di satu record. Kedua, tidak ada karakter yang hilang atau bertambah di sambungannya.
Di sinilah panel DNS berbeda-beda perilakunya. Ada yang memecah otomatis dengan benar. Ada yang mengharapkan kamu menulis sendiri potongannya dalam tanda kutip. Ada juga yang diam-diam memotong di karakter ke-255. Karena perilakunya tergantung panel, cara paling aman adalah mengecek hasil akhirnya lewat DNS.
Langkah 1: lihat record mentah apa adanya
selector dan example.com dengan milikmu.
BASH
# cari nameserver authoritative domain
dig +short NS example.com
# query record DKIM langsung ke salah satu nameserver tersebut
dig +short TXT 'selector._domainkey.example.com' @ns1.example-dns.net
# tampilkan jumlah record (tiap baris di ANSWER = satu record)
dig TXT 'selector._domainkey.example.com' @ns1.example-dns.net +noall +answerTEXT
# Contoh format output: satu record, dua string (normal)
"v=DKIM1; k=rsa; p=MIIBIjANBgkq...potongan-pertama" "potongan-kedua..."
# Contoh format output: terpecah jadi dua record terpisah (rusak)
"v=DKIM1; k=rsa; p=MIIBIjANBgkq...potongan-pertama"
"potongan-kedua..."
# Contoh format output: tanda kutip ikut tersimpan sebagai isi (rusak)
"\"v=DKIM1; k=rsa; p=MIIBIjANBgkq...\" \"potongan-kedua...\""\".
Ada juga kerusakan yang tidak kelihatan dari struktur. Contohnya spasi atau line break yang ikut ter-copy di tengah key dari halaman provider, satu-dua karakter yang hilang di titik potong, atau key yang terpotong di 255 karakter tanpa sisa. Untuk kasus seperti ini, membaca dengan mata tidak cukup. Kamu perlu membandingkan secara byte.
Langkah 2: gabungkan dan bandingkan dengan key dari provider
" " antar string, buang tanda kutip pembuka dan penutup, lalu ambil nilai p=. Simpan key asli dari provider email ke file provider.txt (cukup nilai p=-nya saja), lalu bandingkan keduanya.
BASH
# gabungkan string seperti verifier: hapus batas " " lalu sisa tanda kutip
dig +short TXT 'selector._domainkey.example.com' @ns1.example-dns.net \
| sed -e 's/" "//g' -e 's/"//g' \
| grep -o 'p=[^;]*' | cut -d= -f2- | tr -d '
' > dns.txt
# bersihkan key dari provider (spasi, line break, CR dari copy-paste)
tr -d '
\r' < provider.txt > provider-clean.txt
# bandingkan byte per byte, lalu cek panjangnya
cmp dns.txt provider-clean.txt && echo 'SAMA'
wc -c dns.txt provider-clean.txt
# pastikan key yang ada di DNS bisa diparse sebagai public key 2048-bit
base64 -d dns.txt | openssl pkey -pubin -inform DER -noout -text | head -n 1cmp menyebut posisi byte yang berbeda, posisi itu biasanya tepat di titik potong antar string. Dari situ kamu bisa melihat apakah ada karakter yang hilang atau dobel. Kalau panjang dns.txt berhenti di sekitar 240-an karakter, besar kemungkinan panel memotong di batas 255 dan membuang sisanya.
Perintah openssl di akhir adalah pengecekan kedua yang tidak bergantung pada file dari provider. Key yang sehat akan menampilkan baris seperti Public-Key: (2048 bit). Kalau keluar error seperti "could not read key" atau "unable to load", base64-nya rusak, walaupun sekilas terlihat wajar.
Kalau kamu memakai OpenDKIM di server sendiri, opendkim-testkey juga bisa dipakai untuk mencocokkan record DNS dengan private key lokal. Opsi persisnya tergantung versi yang terpasang.
Perintah di atas hanya membaca data, jadi aman dijalankan di server produksi. Hapus dns.txt dan file bantu lainnya setelah selesai.
Hal yang sering bikin salah arah
selector._domainkey.example.com di kolom nama, hasilnya bisa jadi selector._domainkey.example.com.example.com. Gejalanya: dig ke nama yang benar tidak mengembalikan apa-apa, dan header menyebut tidak ada key. Coba query ke nama yang dobel itu untuk memastikan.
Cek juga apakah selector-nya memakai CNAME ke provider. Beberapa layanan email meminta CNAME, bukan TXT. Dalam kasus itu, record TXT-nya dikelola provider, dan dig akan mengikuti CNAME-nya. Kalau hasil akhirnya rusak, masalahnya ada di sisi provider atau di target CNAME yang salah ketik, bukan di pemecahan string milikmu.
Jangan juga langsung percaya pada checker online yang bilang "valid". Checker itu bisa membaca dari resolver yang masih menyimpan record lama, atau dari resolver yang sudah melihat record baru, padahal resolver penerima email belum. Setelah memperbaiki record, tunggu sampai TTL record lama habis sebelum menyimpulkan perbaikan berhasil atau gagal. Query ke nameserver authoritative seperti di Langkah 1 tetap jadi patokan utama.
Terakhir, pastikan hanya ada satu record TXT di nama selector tersebut. Sisa record lama dari percobaan sebelumnya, misalnya key 1024-bit yang belum dihapus, sama merusaknya dengan record yang terpecah jadi dua.
Setelah record DNS terbukti benar dan DKIM lolos, pastikan juga domain penandatangan sejalan dengan domain di header From:. Penerima besar seperti Gmail dan Yahoo mewajibkan SPF, DKIM, dan DMARC untuk bulk sender, dan DMARC hanya lolos kalau alignment-nya cocok. Untuk server cPanel dengan Exim, konteks lengkapnya ada di panduan SPF, DKIM, dan DMARC pada Exim cPanel.
Intinya, jangan menilai record DKIM 2048-bit dari tampilan di form panel. Ambil langsung dari nameserver authoritative, pastikan cuma ada satu record, gabungkan potongannya seperti cara verifier, lalu bandingkan byte per byte dengan key dari provider dan parse dengan openssl. Kalau ketiganya lolos, record DNS-mu sudah benar, dan kalau DKIM masih gagal, penyebabnya ada di tempat lain.