Sebuah situs klien yang berjalan di instance AWS EC2 tiba-tiba kehilangan semua email transaksionalnya. Email verifikasi akun tidak terkirim, reset password tidak pernah sampai, notifikasi berhenti total. Semuanya mati serentak. Dan yang ini bukan tipe gagal yang diam-diam: begitu saya tempel logger di jalur pengiriman, wp_mail() melempar pesan yang sangat eksplisit: Could not instantiate mail function.
Error yang jujur seharusnya kabar baik. Tapi pesan ini tetap membingungkan kalau kamu baru pertama ketemu. Fungsi mail yang mana? Instantiate apa? Kodenya kan tidak berubah sama sekali.
Jalan buntu pertama: curiga ke kode sendiri
Refleks pertama saya standar: pasti ada yang salah di kode. Saya baca ulang jalur pengiriman email di theme, cek argumen wp_mail(), cek header, cek apakah ada plugin yang ikut menyentuh mailer. Semuanya bersih. Kode theme benar, dipanggil dengan data yang benar, dan error yang sama tetap muncul bahkan untuk email paling sederhana sekalipun. Ini bukan bug di level aplikasi.
Jalan buntu kedua: SMTP klasik dengan App Password
Kalau transport bawaan bermasalah, jalur klasiknya jelas: arahkan WordPress ke SMTP Gmail dengan autentikasi user dan password, biasanya lewat App Password. Klien memakai Google Workspace, jadi harusnya tinggal generate App Password, isi kredensial, selesai.
Kecuali: tidak bisa. Di organisasi Google Workspace klien, App Passwords dinonaktifkan di level admin. Seluruh jalur autentikasi user-password untuk SMTP praktis tertutup. Jalur yang paling sering direkomendasikan tutorial justru terkunci rapat oleh kebijakan org.
Akar masalah: EC2 mentah tidak punya kurir surat
Di sinilah pesan error itu akhirnya masuk akal. Di WordPress, wp_mail() mendelegasikan pengiriman ke PHPMailer, dan secara default PHPMailer memakai fungsi mail() milik PHP. Fungsi mail() sendiri tidak mengirim apa pun ke internet; dia hanya menyerahkan pesan ke mail transport lokal di server, biasanya binary sendmail atau postfix. Pesan Could not instantiate mail function artinya persis itu: PHPMailer mencoba memanggil transport lokal, dan transportnya tidak ada.
Dan memang tidak ada. Instance EC2 mentah tidak datang dengan mail transport sama sekali. Tidak ada sendmail, tidak ada postfix, tidak ada apa pun yang bisa menerima surat dari PHP.
which sendmail
# kosong, tidak ada hasilDi hosting managed kita tidak pernah memikirkan lapisan ini karena host sudah menyediakan relay bawaan, jadi email terasa "just works". Di EC2, kamu mulai dari server kosong, dan kemampuan mengirim email adalah infrastruktur yang harus kamu sediakan sendiri.
Perbaikannya: relay SMTP Google Workspace, autentikasi via IP
Karena App Passwords mati, saya butuh jalur yang tidak butuh password sama sekali. Google Workspace punya itu: SMTP relay service, yang bisa mengautentikasi berdasarkan alamat IP pengirim, bukan kredensial.
Setupnya dua sisi. Sisi Google dulu: di Admin console, masuk ke pengaturan Gmail, bagian Routing, lalu SMTP relay service. Di sana saya daftarkan IP statis EC2 ke allowlist. Dengan itu, Google mempercayai koneksi yang datang dari IP tersebut tanpa perlu user dan password.
Sisi WordPress: arahkan PHPMailer ke relay lewat hook phpmailer_init:
add_action( 'phpmailer_init', function ( $mailer ) {
$mailer->isSMTP();
$mailer->Host = 'smtp-relay.gmail.com';
$mailer->Port = 587;
$mailer->SMTPAuth = false;
$mailer->SMTPSecure = 'tls';
$mailer->setFrom( 'no-reply@domain-klien.com' );
}, 5 );Perhatikan SMTPAuth = false: tidak ada kredensial sama sekali di konfigurasi ini. Koneksi menuju smtp-relay.gmail.com di port 587 dengan STARTTLS, dan identitas pengirimnya adalah IP server itu sendiri. Alamat From memakai no-reply di domain klien. Prioritas 5 memastikan hook ini jalan lebih awal, sebelum ada kode lain yang sempat menyentuh konfigurasi mailer.
Hasil pengujian: server relay menjawab 250 OK, dan emailnya bukan sekadar terkirim, tapi mendarat di tab Primary inbox, bukan di spam. Verifikasi akun, reset password, dan notifikasi hidup lagi semua.
Pelajaran
Could not instantiate mail functionhampir selalu berarti server tidak punya mail transport lokal. Ini masalah infrastruktur, bukan bug di kode kamu.- EC2 mentah tidak menyediakan apa pun untuk email. Kalau situs pindah dari hosting managed ke EC2, pengiriman email wajib masuk checklist migrasi.
- App Passwords bisa saja dinonaktifkan di level organisasi Google Workspace. Jangan bangun rencana di atas asumsi jalur user-password selalu tersedia.
- SMTP relay Google Workspace dengan allowlist IP adalah jalur tanpa password yang bersih:
smtp-relay.gmail.com, port 587,SMTPAuthfalse, STARTTLS, diwire lewatphpmailer_init.
