Skenario klasik Senin pagi
Anda baru saja menyelesaikan migrasi IMAP ke Exchange Online. Batch selesai tanpa error di Exchange Admin Center, kotak surat sudah tersinkronisasi, pengguna bisa login. Anda menutup laptop Jumat malam dengan perasaan pekerjaan sudah beres.
Senin pagi, tiket masuk bertubi-tubi. "Semua email saya bertanggal Jumat." "Riwayat kotak masuk saya tidak bisa dipakai." "Email lama saya hilang." Tidak ada yang hilang, sebenarnya: emailnya ada, tapi Outlook menampilkan semuanya dengan tanggal migrasi, bukan tanggal pengiriman asli. Email dari 2019 muncul bertanggal Jumat kemarin. Hasilnya: seluruh kotak surat seolah hanya berisi pesan-pesan baru.
Ini salah satu masalah paling menjengkelkan dari migrasi IMAP ke Exchange Online, dan hampir selalu kurang terdokumentasi oleh Microsoft.
Mengapa migrasi via EAC merusak tanggal
Ketika Anda menggunakan Exchange Admin Center (EAC) untuk mengonfigurasi migrasi IMAP dari server lokal (Dovecot, Courier, Cyrus, UW-IMAP, atau lainnya), Exchange Online terhubung ke server sumber via IMAP, mengambil pesan-pesan tersebut, lalu menyuntikkannya ke kotak surat tujuan melalui pipeline transport internal miliknya sendiri.
Di sinilah masalah itu tercipta.
Setiap email yang melewati pipeline transport Exchange secara otomatis mendapatkan header Received: dengan cap waktu. Ini adalah perilaku standar server SMTP dan IMAP selama puluhan tahun: setiap server yang menyentuh sebuah pesan akan menambahkan tanda waktu miliknya. Masalahnya, Outlook (khususnya Outlook untuk Windows di versi-versi terbaru) menggunakan header Received: paling baru sebagai referensi tampilan ketika metadata lain bersifat ambigu.
Header Date: asli (yang menunjukkan kapan email benar-benar dikirim, sesuai RFC 2822) masih ada di dalam pesan. Tidak dihapus. Tapi ia "tertutup" oleh header Received: baru yang ditambahkan Exchange saat injeksi.
Selain itu, INTERNALDATE IMAP (metadata yang digunakan server IMAP untuk memberi tanggal pada pesan secara internal dan mengontrol pengurutan di sebagian besar klien email) diatur ke tanggal injeksi, bukan tanggal asli email. Exchange Online tidak memiliki cara bawaan untuk mempertahankan INTERNALDATE dari server sumber saat migrasi batch via EAC.
EAC vs. alat pihak ketiga: perbedaan penting
Ada dua situasi yang perlu dibedakan. Dengan alat seperti BitTitan MigrationWiz atau CloudM Migrate, masalah ini juga ada, tapi alat-alat tersebut terkadang memiliki opsi konfigurasi (terdokumentasi sebagian, sering tersembunyi di pengaturan lanjutan) yang mencoba mempertahankan sebagian metadata tanggal.
Migrasi native via EAC tidak menawarkan opsi semacam itu sama sekali. Microsoft tidak mengekspos parameter untuk mengontrol preservasi INTERNALDATE dalam pipeline migrasi batch. Ini kotak hitam: Anda mengonfigurasi batch, Anda menjalankannya, Exchange melakukan apa yang dianggapnya perlu secara internal. Dan yang dilakukannya secara konsisten adalah memberi tanggal pesan sesuai waktu injeksi.
(Omong-omong, jika Anda pernah mencoba membaca header mentah email yang dimigrasi via EAC, Anda tahu bahwa field Received: yang ditambahkan Exchange sangat mudah dikenali: berisi referensi ke server internal Microsoft seperti *.protection.outlook.com atau *.prod.exchangelabs.com, dengan cap waktu yang tepat sesuai jendela migrasi.)
Mengapa membuat ulang batch tidak menyelesaikan masalah
Reaksi spontan banyak admin IT menghadapi masalah ini adalah berpikir: "Kalau saya hapus kotak surat yang sudah dimigrasi dan jalankan ulang batch dari nol, mungkin kali ini tanggalnya benar."
Ini bisa dimaklumi. Tapi tidak akan berhasil.
Masalahnya bukan di konfigurasi batch. Bukan di parameter yang lupa dicentang. Masalahnya ada di arsitektur pipeline transport Exchange itu sendiri, yang identik di setiap migrasi. Menjalankan ulang batch akan menghasilkan hal yang persis sama: header Received: dengan tanggal migrasi baru, dan INTERNALDATE yang salah lagi. Waktu terbuang dan pengguna terganggu untuk kedua kalinya tanpa hasil.
Sebagian admin juga mencoba mengubah pengaturan pengurutan di Outlook ("urutkan berdasarkan tanggal kirim" bukan "tanggal terima"). Pengurutan berdasarkan tanggal kirim bukan solusi. Itu hanya plester. Header Date: dan INTERNALDATE tetap salah untuk klien yang tidak memiliki pengaturan ini, untuk OWA, untuk Outlook Mobile, dan untuk semua aplikasi pihak ketiga yang mengakses kotak surat via IMAP atau EWS.
Apa yang sebenarnya terjadi di header email
Berikut contoh sederhana isi sebuah email setelah migrasi via EAC. Header aslinya:
Date: Thu, 14 Mar 2019 09:23:11 +0100
From: alice@domainlama.com
Subject: Laporan Q1 2019
Setelah migrasi, pesan menerima tambahan di awal rantai header, kurang lebih seperti ini:
Received: from DB7PR0101MB3304.eurprd01.prod.exchangelabs.com
by DB7PR0101MB3305.eurprd01.prod.exchangelabs.com
with HTTPS; Fri, 7 Jun 2024 22:41:03 +0000
Outlook melihat header Received: ini pertama kali (karena ditambahkan di bagian atas blok header), menginterpretasinya sebagai tanggal pemrosesan pesan terbaru, dan menampilkannya sebagai tanggal penerimaan. Header Date: asli dari 2019 masih ada, utuh, beberapa baris di bawahnya. Tapi Outlook tidak menggunakannya untuk tampilan di daftar pesan.
Untuk lebih tepatnya: perilaku ini sedikit berbeda tergantung versi Outlook. Versi pasca-2021 (terutama Outlook baru untuk Windows yang diluncurkan sejak akhir 2023) sangat rentan terhadap masalah ini karena lebih bergantung pada metadata Exchange Graph daripada header Date: mentah. Artinya, migrasi yang dulu tidak menimbulkan masalah terlihat di Outlook 2016 sekarang bisa bermasalah dengan Outlook baru.
Siapa yang paling terdampak
Server IMAP sumber yang paling umum dalam jenis migrasi ini adalah Dovecot (sangat populer di lingkungan Linux/cPanel) dan Courier. Keduanya mengekspos INTERNALDATE via IMAP yang tidak dipertahankan oleh EAC. Jika Anda bermigrasi dari server Exchange on-premises ke Exchange Online (migrasi hybrid atau cutover), perilakunya berbeda karena Microsoft menggunakan protokol transport internal (MAPI/EWS) yang lebih baik dalam mempertahankan metadata. Migrasi IMAP generik via EAC-lah yang bermasalah.
Pengguna yang paling terdampak adalah mereka yang memiliki kotak surat dengan riwayat panjang (5 tahun ke atas) dan volume pesan yang besar. Pengguna dengan 300 email di kotak masuknya akan pulih dengan cepat. Seorang manajer penjualan dengan 12.000 email yang diurutkan berdasarkan tanggal, yang setiap hari mengandalkannya untuk menemukan kembali percakapan dengan klien, dia benar-benar terhenti.
Mengapa script buatan sendiri adalah ide buruk di sini
Sebagian admin IT yang memahami masalah teknis ini tergoda untuk menulis script PowerShell atau Python guna memperbaiki header secara manual. Konsep dasarnya mungkin terlihat sederhana setelah mekanismenya diidentifikasi. Tapi kenyataan koreksi di lingkungan produksi adalah urusan lain.
Pertama, kasus-kasus tepi. Email yang ditandatangani S/MIME dan pesan terenkripsi PGP memiliki struktur yang tidak toleran terhadap modifikasi header tanpa membatalkan tanda tangan. Pesan multipart/alternative dengan batas MIME yang tidak terbentuk dengan baik (umum di server Courier lama) bisa rusak oleh script yang memodifikasi pesan tanpa merekonstruksi strukturnya dengan benar. Header non-ASCII yang dienkode sesuai RFC 2047 (nama pengirim dengan karakter beraksen atau huruf Jepang, misalnya) adalah sumber kesalahan klasik.
Kemudian, soal volume. Script yang berfungsi untuk 50 email uji di lingkungan pengembangan tidak akan menangani batas laju API Exchange Online di produksi. Error 429 Too Many Requests pukul 2 pagi selama batch 8.000 pesan, tanpa mekanisme pemulihan, adalah begadang semalaman dan berpotensi pesan ganda atau hilang.
Dan yang terpenting: bagaimana cara memverifikasi bahwa setiap email yang dikoreksi masih utuh? Bahwa tidak ada lampiran yang terpotong, tidak ada utas diskusi yang rusak, bahwa label dan folder terjaga? Tanpa mekanisme validasi individual, kita hanya berharap semuanya berjalan baik.
Koreksi tanggal setelah migrasi adalah masalah yang terlihat seperti script 50 baris tapi membutuhkan ribuan baris untuk bisa diandalkan di produksi.
Apa yang dilakukan Redate.io secara berbeda
Redate.io terhubung ke Exchange Online via API Microsoft 365 (Azure Active Directory, izin delegasi di tingkat tenant) dan memindai kotak surat yang bersangkutan untuk mengidentifikasi email yang metadata tanggalnya telah rusak akibat migrasi. Tahap pemindaian ini gratis dan memberikan gambaran akurat tentang seberapa luas masalah: jumlah pesan yang terdampak, kotak surat yang terpengaruh, rentang tanggal yang rusak.
Mesin koreksi milik Redate.io kemudian memproses setiap email secara individual melalui pipeline analisis multi-tahap yang mencakup pencocokan pola terhadap tanda tangan alat migrasi yang dikenal (termasuk pipeline transport Exchange Online), validasi kepatuhan RFC, dan verifikasi integritas struktural pesan sebelum dan sesudah koreksi. Email bertanda tangan S/MIME, struktur MIME kompleks, encoding non-standar: semuanya ditangani melalui jalur pemrosesan khusus.
Setiap pesan yang dikoreksi diverifikasi secara individual. Salinan aslinya disimpan di folder cadangan yang terlihat selama 30 hari. Jika ada yang tidak beres dengan pesan tertentu, pesan itu tidak dimodifikasi: Redate.io melaporkan anomali tersebut daripada mengambil risiko kerusakan data.
Harganya berbasis volume, dengan pembayaran satu kali per kotak surat. Tidak ada langganan, tidak ada biaya berulang. Anda memperbaiki masalah satu kali, selesai.
Untuk migrasi Exchange Online secara khusus, Redate.io mendukung koneksi via izin aplikasi Azure AD (tanpa harus membuat kredensial individual per kotak surat), yang membuat pemrosesan sejumlah besar kotak surat jauh lebih mudah dikelola bagi admin IT atau MSP.
Jika Anda mengelola beberapa klien yang mengalami jenis migrasi ini, lihat juga panduan lengkap koreksi tanggal setelah migrasi Microsoft 365 untuk gambaran menyeluruh berbagai skenario yang ditangani.
Email-emailnya ada, tanggal aslinya pun ada. Jalankan pemindaian gratis di Redate.io untuk melihat persis berapa banyak pesan yang terdampak di kotak surat Exchange Online Anda, sebelum memutuskan langkah selanjutnya.