imapsyncで日付が保持されない場合の修正方法

1分で読めます 最終更新日:

--syncinternaldatesの約束(そして、その限界)

imapsyncコマンドを実行しました。ドキュメントを読んで、慎重な人なので--syncinternaldatesを含めました。移行が完了し、ログにはすべて転送済み、エラーゼロと表示されます。それからOutlookでメールボックスを開くと、すべてのメールが昨日の日付を表示しています。

これはimapsyncで最もよくあるフラストレーションの一つで、少なくとも2017年からシステム管理者を混乱させてきました。--syncinternaldatesフラグは、移行中にIMAPのINTERNALDATEを保持するためのものです。実際にそうします。各コピーに、元サーバーが保持している内部日付を与えるのです。まさにそこに、落とし穴があります。

imapsyncはGilles Lamiral氏が書いたオープンソースのPerlツールで、その役割において本当に優れています。ほとんどの商用ツールがうらやむレベルの信頼性で、IMAP間のメールボックス転送を処理します。しかしimapsyncは、見つけた日付をコピーすることしかできません。そこで事態が複雑になります。

IMAPの日付が実際にどう機能するか

すべてのメールには3つの異なる「日付」が関わっており、ほとんどの人(一部のIT担当者を含む)がそれらを混同しています。

  • Date:ヘッダー(RFC 2822) - 送信者のメールクライアントが、メッセージ作成時に付けた日付です。メッセージ本文の中にあり、メールサーバーが変更することはありません。
  • Received:ヘッダー - メッセージを処理する各メールサーバーが、自身のタイムスタンプ付きで追加します。送信者から受信者への連鎖を形成します。最新のReceived:ヘッダーが、一部のメールクライアントが表示に使うものです。
  • INTERNALDATE - メールボックス内でメッセージを並べる順序を制御する、IMAPサーバー側のタイムスタンプです。IMAP APPENDでメッセージが最初に保存されたときに設定されます。

imapsyncがメッセージを移行する際、元サーバーからメッセージを(INTERNALDATEも含めて)読み取り、IMAP APPENDを使って宛先サーバーに書き込みます。--syncinternaldatesフラグは、APPENDの際に元のINTERNALDATEを宛先サーバーに渡すよう、imapsyncに指示します。

良い知らせがあります。Microsoft 365、Outlook.com、Gmailは、渡された日付をそのまま保持します。ですから、日付が間違って表示されるとき、問題は別の場所にあります。

それでも日付が間違ってしまう理由

IMAP仕様(RFC 3501)では、APPENDコマンドで日時が渡された場合、サーバーはそれを使う「べき(SHOULD)」とされています。RFCの言葉で「SHOULD」とは「良い理由がない限りそうしなさい」という意味です。Microsoft 365、Outlook.com、Gmailはまさにその通りにします。元の日付を持って渡されたコピーは、その日付を保持します。

とはいえ、imapsyncが渡すのは、各メッセージについて元サーバーが保持している日付であり、メールが送信された日付そのものではありません。健全なメールボックスなら、両者は一致します。しかし、一度すでに移行された、あるいはバックアップから復元されたメールボックスでは、元サーバーがその以前の操作の日付を保持している場合があり、imapsyncはそれをそのままコピーします。

Gmailが特殊なケースとなるのは、コピーがIMAPではなくGmail独自のインポートAPIを経由する場合だけです。そのAPIはコピーの日付が入ったReceived:行を追加し、Outlookがその日付を表示することがあります。imapsyncはIMAPで通信するため、この影響を受けません。

最も普及している2つのオープンソースIMAPサーバー、DovecotとCyrusも、APPENDからの日付を保持します。つまり、宛先が何であれ、問いは同じです。元サーバーはどの日付を保持していたのか、ということです。

日付を狂わせるimapsyncコマンドラインのよくある間違い

元サーバーの日付以外にも、管理者はimapsyncのコマンドラインオプションでつまずいたり、間違ったオプションを責めたりすることがよくあります。よく見かける間違いを挙げます。

元の日付がすでに間違っているソースからコピーする

--syncinternaldatesはデフォルトで有効です。imapsyncは各コピーに、元サーバーが保持している内部日付を与えます(ドキュメントの表現では「host2の内部日付をhost1と同じに設定する」)。元のメールボックス自体が、以前の移行や復元の結果であれば、その内部日付はすでにその操作のときのものになっている可能性があり、imapsyncは間違った日付をそのまま忠実にコピーします。これが最も多い原因であり、最も見落としやすいものです。ログには同一の日付が2つ表示されるからです。

--syncinternaldatesと--addheaderの併用

一部のガイドは、移行中にカスタムヘッダーを挿入するため--addheaderを使うよう勧めています。ヘッダーを追加するとメッセージは変わります(先頭に一行増えるだけです)が、imapsyncが渡す日付は変わりません。ですから、これが間違った日付の説明にはなりません。単に、コピーが元とまったく同一ではなくなるだけであり、両者を比較する場合にはそれが問題になります。

--minageと--maxageを日付の保持と混同する

--minageと--maxageフラグは、経過時間に基づいて移行するメッセージを絞り込むものです。宛先での日付の扱いには影響しません。この2つのフラグを何時間もいじって、日付の問題が直ると思っている管理者を見てきました。直りません。

日付のずれをTLSのせいにする

TLS経由(--ssl1、--ssl2)では、接続の確立にレイテンシーが加わり、大規模な移行(5万通以上)では、それが積み重なって数時間になることもあります。しかし日付には影響しません。各コピーは、実際にいつ到着しようと、imapsyncが渡した日付をそのまま持っています。

imapsyncログの読み方:出力が実際に伝えていること

imapsyncは詳細なログを出力します。これは良いことです。しかし、日付に関しては、そのログ出力が誤解を招くことがあります。

典型的な成功した転送の行は、こう表示されます。

msg source stratemind/42 {5765} D:2019-01-15 13:22:07 -> dest stratemind/42 {5765} D:2019-01-15 13:22:07

両方の日付が一致しています。これはimapsyncが正しいINTERNALDATEを宛先に送ったことを意味します。そしてMicrosoft 365、Outlook.com、Gmailはいずれも、渡された日付をそのまま保持します。しかし、2つの日付が同一であることは、コピーが元(ソース)に忠実であることしか証明しません。元の日付がすでに間違っていた場合、両方の列に同じ間違った日付が表示されます。

実際に何が起きたのかを確かめたいですか。移行後、IMAPクライアントで宛先に接続し、INTERNALDATEを直接確認してください。

a1 SELECT INBOX
a2 FETCH 42 (INTERNALDATE)

返ってきた日付がメールの送信日でない場合は、元(ソース)にある同じメッセージを確認してください。そこにも同じ間違った日付が見つかるはずです。ログは嘘をついていません。渡されたものをそのままコピーしただけです。

これは日付の問題を調べるときに最もいらだたしい点の一つです。きれいなログファイル、2つの同一の日付、それでもOutlookでは間違った日付が表示されます。なぜなら、その誤りはimapsyncが実行される前から存在していたからです。

大規模なimapsync移行:日付の問題が増える場所

imapsyncによる単一メールボックスの移行でも、日付がおかしくなれば煩わしいものです。しかし、数百のメールボックスに対してimapsyncを実行するMSPやIT部門は、まったく違う規模の問題に直面します。

典型的な企業移行のシナリオを考えてみましょう。ZimbraサーバーからMicrosoft 365へ、200のメールボックスを移す場面です。ユーザーのCSVをループするラッパースクリプトを書き、各ユーザーに対してimapsyncを呼び出します。移行は週末にかけて実行されます。月曜の朝、200のメールボックスで日付が間違っており、合計約120万件のメールが移行時のタイムスタンプを表示しています。

imapsyncを再実行して直せるでしょうか。技術的には可能ですが、imapsyncは宛先にすでに存在するメッセージをスキップします(冪等になるよう設計されているためです)。宛先のメッセージを削除して再転送するには--delete2が必要になり、稼働中のメールボックスでは危険です。そして、元の日付そのものが問題だった場合、2回目の実行でも同じ間違った日付が再びコピーされるだけです。

一部の管理者は、まず--dryでimapsyncを試し、それから本番の移行を行うという折衷案を試みます。しかし--dryは転送を模擬するだけです。imapsyncが渡すはずの日付を表示するのであって、それがメールの送信日と一致しているかどうかは示しません。元の日付がすでに間違っていることを、何も警告してくれないのです。

自力での修正とその限界

フォーラムやメーリングリストを検索すると(SourceForgeのimapsync-develリストは、2026年初めの時点でもまだ活発です)、創造的なものから危険なものまで、さまざまな提案が見つかります。

宛先サーバーのINTERNALDATEを直接変更するために、Perlのワンライナーを使うことを勧める人もいます。すべてのメッセージをmbox形式にエクスポートし、日付を操作してから再インポートすることを勧める人もいます。imaplibを使って、メッセージを取得、変更、再挿入するPythonスクリプトを書いた人もいます。

これらのアプローチはすべて、同じ根本的な問題を抱えています。署名を壊さずにS/MIME署名付きメッセージをどう扱うのでしょうか。入れ子になった境界を持つマルチパートMIME構造はどうでしょうか。RFC 2047でエンコードされた非ASCIIヘッダーは。内容を確認することさえできないPGP暗号化メッセージは。開発環境で50件のテストメッセージを処理できるスクリプトは、3万件の本番メールボックスにあるエッジケースで必ず詰まります。

そして、手遅れになるまで誰も問わない最大の疑問があります。変更した一件一件のメッセージが、なお無傷であることを、どうやって確認するのでしょうか。添付ファイルが壊れていないこと、スレッドがまだ機能していること、2020年に誰かが送った85MBのスプレッドシートが、その操作を経ても無事だったこと、それをどう確かめるのでしょうか。

(Perlで生のメールヘッダーを解析しようとしたことがあるなら、それがのんびりした午後の過ごし方とは言えないことをご存じでしょう。)

Redate.ioがimapsyncの日付問題をどう修正するか

元のDate:ヘッダーは、imapsync移行の後も常に無傷です。imapsyncは生のメッセージを忠実に転送します。間違った日付は、メッセージの中ではなく、コピーが受け取ったメタデータの中にあります。この元のヘッダーがあるからこそ、修正が可能になります。

Redate.io はメールボックス(Google Workspace、Microsoft 365、または任意のIMAPサーバー)に直接接続し、日付に異常のあるメールをスキャンし、独自のヘッダーチェーン分析と日付再構築パイプラインによって、的を絞ったメタデータ修正を適用します。どのツールが移行を行ったかを知る必要はありません。表示されている日付が元の日付と一致しないメールを見つけるだけです。

修正された各メールは個別に検証されます。メッセージの整合性、添付ファイルの保持、フォルダーの配置、スレッド、ラベルです。元のメールは、目に見えるRedate.io - Originalsバックアップフォルダーに保管され、自分で削除するまでそこに残ります。何か問題があるように見えたら、ワンクリックで元に戻せます。

無料スキャンはメールボックスに接続し、日付に異常のあるメールをすべて特定し、正確な件数と費用を提示します。クレジットカードは不要で、ソフトウェアのインストールも不要です。お使いのプラットフォームごとの詳細は、こちらをご覧ください。

Redate.ioは数か月前や数年前に行われた移行にも対応します。Date:ヘッダーには有効期限がなく、問題を修正する力も同じです。

imapsyncで移行して、日付が間違ったままになっていますか? 無料スキャンを実行すると、影響を受けているメールの正確な数がわかります。

関連記事