Два Outlook, два разных поведения с одинаковыми письмами
Если вы недавно мигрировали почтовые ящики в Microsoft 365 и некоторые пользователи жалуются, что все старые письма показывают одну и ту же дату (дату миграции), вы, возможно, заметили кое-что странное: пользователи классического Outlook иногда видят правильную дату в панели чтения, а те, кто работает в новом Outlook для Windows, всегда видят дату миграции. Одни и те же ящики. Одни и те же письма. Разные результаты.
Это не баг в строгом смысле. Это архитектурное решение, которое напрямую влияет на отображение дат после миграции по IMAP. Чтобы разобраться в происходящем, нужно погрузиться в детали заголовков писем и протокола IMAP. Не самое лёгкое чтение, но именно это объясняет, почему никакие манипуляции на стороне клиента не решают проблему.
INTERNALDATE в IMAP: настоящий виновник
Когда письмо хранится на IMAP-сервере, у него есть два типа дат, которые сосуществуют и не смешиваются друг с другом.
Первый - заголовок Date:, определённый RFC 2822. Это дата, записанная в самом сообщении, та, которую отправитель указал в момент отправки. Она является частью тела сообщения и никогда не меняется, по какому бы пути письмо ни прошло.
Второй - INTERNALDATE, метаданные, которыми управляет IMAP-сервер, находящиеся за пределами самого сообщения. Это дата, когда сервер зарегистрировал сообщение. При обычной миграции серьёзные инструменты сохраняют исходный INTERNALDATE. Но при неправильно настроенной миграции, или с инструментами, которые некорректно обрабатывают эти метаданные, INTERNALDATE сбрасывается на текущую дату. Результат: все перенесённые письма с точки зрения сервера имеют одинаковую дату получения.
(Кстати, если вы когда-нибудь читали логи imapsync или MigrationWiz, то знаете, что существуют специальные параметры для попытки сохранить INTERNALDATE. Они работают не всегда, а некоторые серверы назначения вообще отказываются их соблюдать.)
Классический Outlook: как он читает даты
Классический Outlook - то есть локально установленные COM-версии (Outlook 2016, 2019, 2021 и настольный клиент Microsoft 365 Apps) - использует несколько более сложный механизм для определения, какую дату показывать в списке сообщений.
Для писем в папке «Отправленные» он опирается на заголовок Date:. Для входящих писем приоритет отдаётся INTERNALDATE сервера, но в некоторых контекстах (особенно когда задействован кэш OST или при первом отображении в панели чтения) он также может читать цепочку заголовков Received: для приблизительного восстановления исходной даты.
Именно поэтому наблюдается такое непоследовательное поведение: классический Outlook порой отображает правильную дату в панели чтения, поскольку читает исходный заголовок Date: для детального предпросмотра, даже если сам список писем использует испорченный INTERNALDATE. Но это ненадёжно и ничего не исправляет. Сортировка остаётся сломанной, поиск по дате - недостоверным.
Новый Outlook: принципиально другая архитектура
Новый Outlook для Windows, который постепенно разворачивается с конца 2023 года, больше не является COM-приложением. По сути, это Progressive Web App (PWA), основанное на той же кодовой базе, что и Outlook в браузере (OWA). Эта переработка имеет глубокие последствия.
Новый Outlook полностью делегирует отображение дат API Microsoft 365. Он не читает заголовки Received:, не копается в цепочке заголовков в поисках исходной даты и не пытается что-то восстанавливать на стороне клиента. Он просто отображает то, что возвращает сервер: INTERNALDATE.
Результат: если INTERNALDATE был испорчен во время миграции, новый Outlook не колеблется ни секунды. Он показывает дату миграции для каждого затронутого письма - без исключений, без нюансов. Это более последовательное и предсказуемое поведение, чем у классического Outlook, но оно делает проблему миграции сразу видимой и невозможной для игнорирования.
Администратор, который мигрировал 300 ящиков в пятницу вечером, обнаружит в понедельник утром, что все пользователи нового Outlook видят свои архивы с датами прошлых выходных. Тикеты летят быстро.
Почему никакие клиентские обходные пути не работают
Многие администраторы пробуют решения на стороне клиента, прежде чем понять, что проблема - в данных на сервере. Вот классические попытки и почему они не дают результата.
Сортировка по «Дате отправки» вместо «Даты получения»
Сортировка по дате отправки в Outlook опирается на заголовок Date: сообщения, который не тронут. Так что да, такая сортировка может работать. Но это пластырь, а не решение. Поиск по дате остаётся сломанным. Правила, основанные на дате, остаются бесполезными. И главное: пользователь должен вручную перенастраивать каждую папку, каждый ящик. На 300 ящиках - нереально. Сортировка по дате отправки не решает проблему, а конечные пользователи не понимают, почему их просят менять привычки.
Очистка кэша Outlook или пересоздание профиля
Это никак не затрагивает INTERNALDATE на сервере. После пересоздания профиля Outlook заново синхронизирует письма с сервера и получает ровно те же испорченные метаданные. Кэш тут ни при чём.
Использование OWA вместо клиента
OWA и новый Outlook используют одну и ту же базу данных. Если INTERNALDATE испорчен на сервере Exchange Online, OWA показывает ровно ту же неправильную дату. Смена клиента не меняет данные.
Проблема находится на сервере, в метаданных каждого сообщения. Никакие действия на стороне клиента не могут исправить данные, хранящиеся на стороне сервера.
Ловушка заголовков Received: почему они всё усложняют
Когда инструмент миграции копирует письмо с одного сервера на другой через IMAP, сервер назначения автоматически добавляет заголовок Received: в начало цепочки с датой и временем вставки. Это нормальное поведение SMTP- и IMAP-серверов, соответствующих RFC.
Эти заголовки накапливаются в обратном порядке относительно пути письма. Самый свежий - вверху. Некоторые почтовые клиенты читают первый Received: для определения даты получения, что даёт дату миграции вместо исходной даты.
Уточнение: такое поведение не является особенностью какого-то одного инструмента. BitTitan MigrationWiz, CloudM, imapsync, GSMMO и даже ручное копирование IMAP между двумя клиентами Thunderbird - все они дают этот результат. Исходный заголовок Date: остаётся нетронутым в сообщении. Именно это технически делает исправление возможным. Но INTERNALDATE - отдельная метаданная, которой управляет сервер, и её нельзя исправить простой манипуляцией заголовками сообщения на стороне клиента.
Подробнее об этом механизме - в статье про IMAP INTERNALDATE и почему ломаются даты, где детально разобрано, как эти метаданные обрабатываются разными серверами.
Какие инструменты миграции вызывают эту проблему в Microsoft 365
Вопрос возникает часто: все ли инструменты миграции провоцируют эту проблему?
Короткий ответ: зависит от конфигурации и платформы назначения. На Exchange Online / Microsoft 365 сервер особенно строг в управлении INTERNALDATE. Даже инструменты, которые пытаются его сохранить, иногда терпят неудачу, поскольку Graph API и EWS (Exchange Web Services) ведут себя по-разному в зависимости от используемого метода вставки.
BitTitan MigrationWiz - один из наиболее распространённых инструментов для миграций в Microsoft 365, и именно его проблемы с датами задокументированы лучше всего. Страница исправление дат миграции BitTitan в Microsoft 365 охватывает специфические конфигурации, на которые стоит обратить внимание. У CloudM и imapsync есть свои особенности, задокументированные соответственно на страницах исправление дат миграции CloudM в Microsoft 365 и исправление дат imapsync в Microsoft 365.
Общее для всех этих инструментов: исходный заголовок Date: выживает при миграции. Это основа, на которой возможно исправление.
Почему самодельный скрипт - плохая идея
Понимание проблемы иногда создаёт иллюзию, что решение простое. Это не так, особенно в производственных масштабах.
Изменить метаданные писем, хранящихся на Exchange Online, нетривиально. Graph API Microsoft накладывает строгие ограничения на частоту запросов (ошибка 429 Too Many Requests в ночном батче появляется очень быстро). Обработка писем, подписанных S/MIME или зашифрованных PGP, требует особого внимания, чтобы не аннулировать подписи. Структуры multipart с объёмными вложениями создают ограничения по сетевым таймаутам. И главное: как проверить, письмо за письмом, что исправление прошло успешно и не повредило содержимое или вложения?
Скрипт, который нормально работает на 50 тестовых письмах, поведёт себя иначе на ящике с 40 000 сообщений и восьмилетней историей. Вероятность того, что граничный случай что-то сломает, растёт с каждой тысячей дополнительных сообщений. А без механизма отката ошибка в середине процесса оставляет ящик в несогласованном состоянии.
Смотрите также: исправить даты писем после миграции Microsoft 365 для полного обзора доступных вариантов.
Что конкретно делает Redate.io
Redate.io: каждый пользователь входит со своей учётной записью Microsoft 365, и Redate.io открывает именно этот почтовый ящик с доступом, который даёт этот вход. Никакого портала, никакого приложения для регистрации. Затем Redate.io бесплатно сканирует письма с неправильными датами и применяет проприетарный механизм исправления к выявленным сообщениям. Многоступенчатый конвейер анализа выполняет сопоставление с сотнями сигнатур известных инструментов миграции, проверку соответствия RFC и анализ цепочки заголовков для восстановления корректных метаданных дат.
Каждое исправленное письмо проверяется индивидуально. Исходные письма остаются в видимой резервной папке вашего почтового ящика, пока вы сами их не удалите. Модель оплаты - единовременный платёж за почтовый ящик, без подписки.
После этого новый Outlook показывает правильные даты, потому что исправлены серверные данные, а не просто скрыта проблема.
У вас есть затронутые ящики в новом Outlook? Запустите бесплатное сканирование на Redate.io, чтобы точно узнать, сколько писем затронуто, прежде чем принимать решение о дальнейших действиях.