사서함에서 무슨 일이 일어난 걸까요
Zoho Mail에서 Microsoft 365로 도메인 마이그레이션을 막 마쳤습니다. Exchange Online 인프라는 구성됐고, 사서함도 프로비저닝됐고, MX 레코드도 업데이트됐어요. 그런데 월요일 아침, 한 사용자가 Outlook을 열었더니 2021년 이메일이 전부 오늘 날짜로 표시됩니다. 다른 사용자는 작년에 받은 메일이 방금 도착한 것처럼 받은 편지함 맨 위에 정렬돼 있고요. 지원 티켓이 쏟아지기 시작합니다.
Outlook 버그가 아닙니다. Zoho에만 국한된 문제도 아니에요. 이건 IMAP에서 Exchange Online으로 마이그레이션할 때 예상되는 동작이지만, 제대로 문서화되지 않은 현상입니다. 정확히 왜 이런 일이 생기는지 이해하는 것이 제대로 수정하기 위한 첫걸음이에요.
기술적 원인: INTERNALDATE와 Received 헤더
IMAP 서버에 저장된 이메일은 두 가지로 구성됩니다. 하나는 메시지의 원시 콘텐츠(RFC 2822 헤더, 본문, 첨부 파일)이고, 다른 하나는 IMAP 서버가 관리하는 저장 메타데이터, 즉 INTERNALDATE입니다. 메일 클라이언트가 메시지를 표시하고 정렬할 때 참조하는 건 바로 이 메타데이터예요.
메시지 원본에 포함된 Date: 헤더(RFC 2822)는 발신자가 메시지를 작성하거나 발송한 날짜를 나타냅니다. 반면 INTERNALDATE는 IMAP 서버가 메시지를 수신하거나 저장한 날짜예요. 정상적인 서버에서는 이 두 값이 비슷합니다. 마이그레이션 후에는 완전히 다른 이야기가 되죠.
IMAP 마이그레이션이 날짜를 망가뜨리는 방식
마이그레이션 도구(Zoho Migration Wizard, imapsync, BitTitan, 기타 모든 도구)가 Zoho Mail에서 Exchange Online으로 메시지를 전송할 때는 IMAP 프로토콜을 사용합니다. 도구가 Zoho에 연결해 메시지를 가져온 뒤, IMAP APPEND 명령으로 Exchange Online에 삽입하는 방식이에요. 문제는 바로 여기서 발생합니다.
Exchange Online은 각 메시지를 수신할 때 새로운 Received: 헤더를 메시지 맨 앞에 추가합니다. 이 헤더에는 삽입된 정확한 날짜와 시간, 즉 마이그레이션 날짜가 기록돼요. 일부 마이그레이션 도구는 APPEND 명령의 파라미터로 원래 INTERNALDATE를 전달해 보존하려 시도합니다. 하지만 그렇게 하지 않거나 잘못 처리하는 도구도 있고, 그럴 경우 Exchange Online이 자동으로 수신 날짜를 INTERNALDATE로 할당해버립니다.
결과는 하나예요. 2019년에 보낸 이메일이든 2022년에 보낸 이메일이든, INTERNALDATE가 마이그레이션이 이루어진 주를 가리키게 됩니다. Outlook은 이 값을 우선적으로 읽습니다. 정렬 순서가 완전히 무너지는 거예요.
Zoho Migration Wizard의 구체적인 동작
Zoho는 자체 플랫폼에서 나가는 마이그레이션을 위해 Zoho Migration Wizard를 제공합니다. 간단한 마이그레이션에는 편리한 도구지만, 관리자 포럼에서 문서화된 동작이 있습니다. 대상 서버에 삽입할 때 원래 INTERNALDATE를 항상 올바르게 전달하지 않는다는 점이에요.
정확히 말하면, 이 문제는 주로 수신되는 모든 메시지에 Received: 헤더를 체계적으로 추가하는 서버로 마이그레이션할 때 발생합니다. Exchange Online이 정확히 그런 동작을 하죠. Zoho Migration Wizard가 APPEND 파라미터로 원래 날짜를 전달하더라도, Exchange Online이 생성한 Received: 헤더가 헤더 체인의 맨 앞에 위치하게 되고, Outlook은 이를 기준으로 "이메일이 도착한 시각"을 판단합니다.
imapsync 같은 범용 IMAP 도구로 Zoho를 떠나는 관리자들도 동일한 문제를 겪습니다. 오히려 더 심한 경우도 있어요. imapsync의 기본 설정이 Exchange Online에 최적화돼 있지 않기 때문입니다. (새벽 2시에 동기화 오류를 찾겠다고 imapsync 로그를 한 줄씩 훑어본 적이 있다면, 이 도구가 강력하지만 엣지 케이스에는 그다지 너그럽지 않다는 걸 잘 아실 겁니다.)
Outlook이 잘못된 날짜를 표시하는 이유
Outlook은 이메일 날짜를 표시할 때 Date: 헤더만 사용하지 않습니다. 대부분의 보기에서, 특히 받은 편지함 정렬에는 IMAP/Exchange 서버가 제공하는 INTERNALDATE가 사용됩니다. 원래 Date: 헤더는 메시지 안에 그대로, 손상되지 않은 채로 있지만, INTERNALDATE에 밀려 무시됩니다.
그래서 Outlook의 "보낸 날짜 기준 정렬" 옵션이 문제를 제대로 해결하지 못하는 겁니다. 다른 날짜가 표시되긴 하지만, 정렬 동작 자체는 Outlook 버전과 보기 모드(대화 그룹 여부)에 따라 여전히 불안정합니다. 보낸 날짜 정렬은 해결책이 아닙니다. 클라이언트 업데이트 한 번이면 떨어져 나가는 임시방편이에요.
문제의 실제 규모
중간 규모의 Zoho에서 Microsoft 365 마이그레이션이라면, 사서함 이력과 조직 규모에 따라 쉽게 5만~50만 개의 메시지가 영향을 받습니다. 마이그레이션 기간에 전송된 모든 이메일이 같은 손상된 날짜를 갖게 되므로, 사용자가 Outlook을 처음 열자마자 문제가 바로 보입니다.
보낸 편지함이 특히 문제가 됩니다. 2022년 3월에 보낸 견적서를 찾는 영업 담당자가 마이그레이션 날짜를 표시하는 수백 개의 이메일 더미를 뒤져야 하는 상황이 생겨요. 이건 단순히 보기 불편한 문제가 아니라, 실제 업무에 영향을 주는 문제입니다.
시간이 지나면 해결될 거라고 생각하기 쉬운데, 그렇지 않아요. INTERNALDATE는 삽입 시점에 고정됩니다. 스스로 수정되지 않아요. 적극적인 조치 없이는 이메일이 손상된 날짜를 영구적으로 유지합니다.
직접 수정하는 게 생각보다 위험한 이유
유혹이 이해됩니다. 원래 Date: 헤더가 메시지 안에 그대로 있으니, 메타데이터만 수정하면 되는 거 아닌가 하는 생각이 들죠. 이론적으로는 맞습니다. 하지만 80,000개 이메일이 든 프로덕션 사서함에서 실행하면 완전히 잘못될 수 있는 작업이에요.
자체 스크립트가 제대로 처리하지 못할 가능성이 높은 엣지 케이스를 몇 가지 들어볼게요:
- S/MIME 서명 이메일. 서명이 모든 헤더를 포함해요. 메시지 구조에서 무언가를 수정하면 암호화 서명이 무효화됩니다.
- PGP 암호화 메시지. 콘텐츠가 불투명하고, MIME 봉투를 조작하면 메시지가 손상될 수 있어요.
- RFC 2047로 인코딩된 비ASCII 헤더(특수 문자가 포함된 발신자 이름). 스크립트가 인코딩을 올바르게 처리하지 않으면 깨집니다.
- 줄 끝이 잘못된 base64 인코딩 첨부 파일, 비표준 MIME 경계, 중첩된 multipart 구조.
- 유효한
Date:헤더가 없는 이메일(실제로 존재합니다, 특히 오래된 Zoho 내보내기 파일에서). 스크립트가 이 경우를 어떻게 처리할지 결정해야 해요.
테스트 이메일 50개에서 작동하는 스크립트가 수년치 이력이 담긴 Zoho 프로덕션 사서함에서는 작동하지 않습니다. 그리고 메시지 하나하나를 확인해서 수정이 온전한지, 첨부 파일이 잘리지 않았는지 어떻게 검증할 건가요? 검증 작업 자체가 수정만큼이나 복잡합니다.
할당량 문제도 있어요. Microsoft Graph를 통한 Exchange Online API는 엄격한 속도 제한을 적용합니다(429 Too Many Requests 오류로 익숙하실 겁니다). 100,000개 메시지에 대한 조절되지 않은 배치 작업은 임시 차단이나, 나중에 진단하기 어려운 조용한 오류를 유발할 수 있어요. 재시작 메커니즘 없이는 처음부터 다시 해야 합니다.
Redate.io가 Zoho 마이그레이션 후 날짜를 수정하는 방법
Redate.io는 글로벌 관리자 권한 없이 표준 Azure AD 권한을 통해 Microsoft 365 테넌트에 연결됩니다. 초기 스캔은 무료입니다. Redate.io가 영향을 받은 사서함을 식별하고, 메시지의 헤더 체인에 담긴 값과 INTERNALDATE를 비교해 날짜가 잘못된 이메일의 수량을 추정해 드립니다.
수정은 독자적인 엔진을 사용합니다. 각 메시지의 전체 헤더 체인을 분석하고, Zoho 마이그레이션 도구(Zoho Migration Wizard든 Zoho에서 나가도록 구성된 imapsync든)의 특정 서명을 식별한 뒤, 다단계 검증 파이프라인을 통해 날짜 메타데이터를 재구성합니다. 수정된 이메일은 하나하나 개별 검증됩니다. 콘텐츠 무결성, 첨부 파일 보존, RFC 준수 여부 모두 확인해요. 원본은 30일간 접근 가능한 백업 폴더에 보관됩니다.
재마이그레이션 없습니다. 다운타임 없습니다. 수정이 백그라운드에서 실행되는 동안 사용자는 Outlook을 계속 사용할 수 있어요.
요금은 구독 없이 볼륨 기반 일회성 결제입니다. 자세한 내용은 사이트에서 직접 확인하세요.
알아두면 좋은 유사 시나리오
여러 마이그레이션을 동시에 관리하거나, MSP로서 Zoho를 떠나는 고객을 담당하고 있다면, 다른 플랫폼에서 Exchange Online으로 마이그레이션할 때도 같은 문제가 발생한다는 점을 기억해두세요. 메커니즘은 동일합니다. Exchange가 생성하는 Received: 헤더가 출처와 관계없이 INTERNALDATE를 덮어씁니다.
Google Workspace, 온프레미스 Exchange, BitTitan MigrationWiz나 CloudM 같은 도구를 통한 마이그레이션의 경우, Redate.io 블로그의 전용 글에서 각 도구별 구체적인 동작을 설명합니다. Exchange Online 마이그레이션 후 이메일 날짜 오류 글에서 이 테넌트에서 발생하는 모든 시나리오에 대한 전체적인 개요를 확인할 수 있습니다.
마이그레이션에 공유 사서함이나 Exchange 리소스(회의실, 장비)가 포함된 경우에도 문제는 동일하며, 같은 수정 도구가 적용됩니다. Zoho를 떠나기 위해 imapsync를 사용하는 팀이라면, imapsync 날짜 보존 안 됨 글에서 imapsync 설정 옵션과 Exchange Online에서 이것만으로는 왜 부족한지를 자세히 다루고 있어요.
BitTitan을 통한 마이그레이션 후 발생하는 날짜 오류라면, BitTitan MigrationWiz 이메일 날짜 오류 수정 글도 참고해보세요.
Outlook에서 Zoho 마이그레이션 날짜가 여전히 잘못 표시되고 있나요? Redate.io에서 무료로 사서함을 스캔해서 어떻게 대응할지 결정하기 전에 문제의 정확한 규모를 파악해보세요.