月曜の朝に届くチケット
Exchange OnlineへのIMAP移行が完了しました。Exchange管理センター(EAC)でバッチはエラーなしで終了し、メールボックスは同期済み、ユーザーはログインできる。金曜の夜、「よし、終わった」という達成感でPCを閉じます。
月曜の朝、チケットが届き始めます。「メールが全部金曜日付になってる」「受信トレイの履歴が使えない」「古いメールが消えた」。実際には消えていません。メールはちゃんとそこにある。ただ、Outlookが移行日の日付で表示しているだけです。2019年のメールが先週の金曜日付で表示される。結果として、メールボックス全体が最近のメッセージしか入っていないように見えてしまいます。
これはExchange OnlineへのIMAP移行で最も厄介な問題のひとつで、Microsoftのドキュメントではほぼ触れられていません。
EAC経由の移行がなぜ日付を壊すのか
EACを使ってオンプレミスサーバー(Dovecot、Courier、Cyrus、UW-IMAPなど)からIMAP移行を設定すると、Exchange OnlineはソースサーバーにいまのサーバーにいまのサーバーにIMAP接続し、メッセージを取得して、Exchange内部のトランスポートパイプラインを通じて宛先のメールボックスに注入します。
問題はここで発生します。
Exchangeのトランスポートパイプラインを通過するすべてのメールには、タイムスタンプ付きの Received: ヘッダーが自動的に付加されます。これはSMTPおよびIMAPサーバーが何十年も前から行っている標準的な動作で、メッセージに触れた各サーバーが自分の時刻スタンプを押します。問題は、Outlook(特にWindows版の最近のバージョン)が、他のメタデータが曖昧な場合に最新の Received: ヘッダーを表示日付の基準として使うことです。
元の Date: ヘッダー(RFC 2822が定義する、実際の送信日時を示すフィールド)はメッセージの中に残っています。削除されていません。しかし、Exchangeが注入時に追加した新しい Received: ヘッダーに「隠されて」しまうのです。
さらに、IMAP INTERNALDATE(IMAPサーバーがメッセージに内部的に割り当てる日付メタデータで、ほとんどのクライアントでの並び順を決める)も、元のメールの日付ではなく注入日時に設定されます。EAC経由のバッチ移行では、Exchange OnlineはソースサーバーのINTERNALDATEを保持するネイティブな手段を持っていません。
EACとサードパーティツールの違い
BitTitan MigrationWiz や CloudM Migrate のようなツールでも同じ問題は発生します。ただし、これらのツールには日付メタデータの保持を試みる設定オプションが(詳細設定の奥深くに、半分ドキュメント化されない形で)存在することがあります。
EACネイティブ移行には、そういったオプションが一切ありません。Microsoftはバッチ移行パイプラインでINTERNALDATEの保持を制御するパラメーターを公開していません。ブラックボックスです。バッチを設定して実行すれば、Exchangeが内部で何をするかはExchange任せ。そして、それは毎回同じことです。注入した日時でメッセージに日付を設定する。
(EAC経由で移行されたメールの生ヘッダーを読んだことがあれば分かると思いますが、Exchangeが追加した Received: フィールドはひと目で分かります。*.protection.outlook.com や *.prod.exchangelabs.com といったMicrosoft内部サーバーへの参照が含まれていて、タイムスタンプはちょうど移行の時間帯に一致しています。)
バッチをやり直しても解決しない理由
この問題に直面したIT管理者がまず考えることは、「移行済みのメールボックスを削除してバッチを最初からやり直せば、今度は日付が正しくなるかもしれない」というものです。
気持ちは分かります。でも、それは機能しません。
問題はバッチの設定にあるわけではありません。チェックし忘れたパラメーターがあるわけでもない。問題はExchangeのトランスポートパイプラインそのものの構造にあり、それはどの移行でも同じです。バッチをやり直せば、まったく同じ結果になります。新しい移行日時を持つ同じ Received: ヘッダー、同じ誤ったINTERNALDATE。時間を無駄にして、ユーザーを再び混乱させるだけです。
Outlookの並び順設定を「受信日」から「送信日」に変えようとする管理者もいます。それは解決策ではありません。応急処置です。その設定ができないクライアント、OWA、Outlook Mobile、IMAPやEWS経由でメールボックスにアクセスするあらゆるサードパーティアプリでは、 Date: ヘッダーとINTERNALDATEは依然として間違ったままです。
ヘッダーで実際に何が起きているか
EAC経由で移行されたメールのヘッダーを簡略化した例を示します。元のヘッダー:
Date: Thu, 14 Mar 2019 09:23:11 +0100
From: alice@olddomain.example
Subject: Q1 2019 レポート
移行後、メッセージのヘッダーチェーンの先頭に次のようなものが追加されます:
Received: from DB7PR0101MB3304.eurprd01.prod.exchangelabs.com
by DB7PR0101MB3305.eurprd01.prod.exchangelabs.com
with HTTPS; Fri, 7 Jun 2024 22:41:03 +0000
Outlookはこの Received: ヘッダーを最初に見ます(ヘッダーブロックの一番上に追加されるため)。これをメッセージの最新処理日として解釈し、受信日として表示します。2019年の元の Date: ヘッダーは数行下にそのまま残っています。でも、Outlookはメッセージ一覧の表示にそれを使いません。
正確に言うと、この動作はOutlookのバージョンによって若干異なります。2021年以降のバージョン(特に2023年末から展開された新しいOutlook for Windows)はこの問題に特に敏感で、生の Date: ヘッダーよりもExchange Graphのメタデータに依存するようになっているからです。つまり、Outlook 2016では問題が出なかった移行が、新しいOutlookでは問題を引き起こすことがあります。
実際に影響を受けるのは誰か
このタイプの移行で最もよく使われるソースIMAPサーバーはDovecot(Linux/cPanel環境で広く普及)とCourierです。どちらもIMAP経由でINTERNALDATEを公開していますが、EACはそれを保持しません。Exchange on-premisesからExchange Onlineへの移行(ハイブリッドまたはカットオーバー)の場合は動作が異なります。Microsoftはメタデータの保持に優れた内部トランスポートプロトコル(MAPI/EWS)を使うためです。問題が起きるのは、EAC経由の汎用IMAP移行です。
最も深刻な影響を受けるのは、長い履歴(5年以上)と大量のメッセージを抱えるメールボックスのユーザーです。300件のメールしかないユーザーならすぐに立て直せます。しかし、顧客とのやり取りを日々日付で検索している営業部長が12,000件のメールを日付順に管理していたとしたら、それは完全に機能停止です。
自作スクリプトがここでは悪手である理由
技術的な問題を理解した管理者の中には、PowerShellやPythonでヘッダーを手動修正するスクリプトを書こうとする人がいます。メカニズムを特定してしまえば、基本的な考え方は単純に見えるかもしれません。でも、本番環境での修正の現実はまったく別の話です。
まず、エッジケースの問題があります。S/MIME署名付きメールやPGP暗号化メッセージは、署名を無効化せずにヘッダーを変更することを許さない構造を持っています。MIMEの境界が不正なmultipart/alternativeメッセージ(古いCourierサーバーではよく見られる)は、構造を正しく再構築せずに変更するスクリプトによって破損する可能性があります。RFC 2047でエンコードされた非ASCIIヘッダー(アクセント文字や日本語が含まれる送信者名など)は、古典的なエラーの発生源です。
次に、ボリュームの問題。開発環境で50件のテストメールで動作するスクリプトが、本番のExchange Online APIのレート制限を処理できるとは限りません。8,000件のバッチを処理中の深夜2時に 429 Too Many Requests エラーが出て、リトライ機構がなければ、それは徹夜であり、場合によってはメッセージの重複や消失です。
そして何より:修正した各メールが完全であることをどうやって確認しますか?添付ファイルが切り捨てられていないか、スレッドが壊れていないか、ラベルとフォルダーが保持されているか?個別の検証メカニズムなしには、ただ「うまくいってくれ」と祈るしかありません。
移行後の日付修正は、50行のスクリプトで済むように見えて、本番環境で信頼性を持たせるには何千行も必要な問題です。
Redate.ioが行うこと
リデイト(Redate.io)はMicrosoft 365 API(Azure Active Directory、テナントレベルの委任権限)を経由してExchange Onlineに接続し、移行によって日付メタデータが破損したメールを特定するために対象メールボックスをスキャンします。このスキャン手順は無料で、問題の正確な規模を把握できます。影響を受けたメッセージ数、対象メールボックス、破損した日付の範囲。
その後、Redate.ioの独自修正エンジンが各メールを個別に処理します。既知の移行ツールのシグネチャ(Exchange Onlineのトランスポートパイプラインを含む)に対するパターンマッチング、RFC準拠の検証、修正前後のメッセージ構造整合性チェックを含む多段階分析パイプラインを使います。S/MIME署名付きメール、複雑なMIME構造、非標準エンコード、これらはすべて専用の処理ルートで対応します。
修正された各メッセージは個別に検証されます。元のメッセージは30日間、見える形でバックアップフォルダーに保持されます。特定のメッセージに問題がある場合、修正は行われません。Redate.ioは破損リスクを冒す代わりに、異常を報告します。
料金はボリューム基準の1回限りの支払いで、メールボックスごとに課金されます。サブスクリプションも継続費用もありません。問題を一度修正すれば、それで終わりです。
Exchange Online移行に特化した話として、Redate.ioはAzure ADのアプリケーション権限経由の接続に対応しています(メールボックスごとに個別の認証情報を作成する必要はありません)。大規模なメールボックスフリートの処理を、IT管理者やMSPにとってはるかにシンプルに調整できます。
複数の顧客がこのタイプの移行を経験している場合は、Microsoft 365移行後の日付修正ガイドも参照してください。さまざまなシナリオを網羅した包括的な内容です。
メールはそこにあります。元の日付も。 Redate.ioで無料スキャンを開始して、Exchange Onlineのメールボックスで実際に何件のメッセージが影響を受けているかを確認してから、次の手を決めてください。