IMAP emails may have incorrect date when Date header is missing #155

Open
opened 2026-04-05 16:16:47 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @prinsss on 10/14/2025

Describe the bug

I found that some emails fetched via IMAP have an incorrect value for the sent_at field. Many archived emails have the time when they are fetched as their Sent date.

It seems that we are currently setting the sent_at field of an email by parsing its raw content with mailparser and reading the Date header (see ImapConnector.ts and mail-parser.js). However, not all emails contain a Date header. In some cases, even the Received header may be absent. This results in fallback to new Date(), causing inaccurate timestamps.

To Reproduce

Steps to reproduce the behavior:

  1. Fetch emails from an IMAP mailbox that contains messages without a Date header.
  2. Observe that the sent_at field for these emails is set to the current time, not the true received time.
👉 Example .eml file

It seems that all emails sent from this address have no Date header. :(

X-QQ-ACTION: no-bounce
X-QQ-mid: newapiserver5t1601234588t12345
X-QQ-INNER-SUBJECT: 
X-QQ-INNER-SUBJECT-ID: -12345
X-QQ-INNER-PENDING: 1
X-QQ-SSF: 0000000000000000000000000000000
X-QQ-STYLE: 4
From:"=?utf-8?B?6IW+6K6v5LqR?=" <cloud_noreply@tencent.com>
To: user@example.com
Subject:=?utf-8?B?5YWz5LqOQ09T5om56YeP5aSE55CG5Y2z5bCG57uT5p2f5YWs5rWL55qE6YCa55+l?=
Content-Type: multipart/alternative;
	boundary="----=_NextPart_4CA2AA3B_66081D78_10BF1234"
Content-Transfer-Encoding:base64

This is a multi-part message in MIME format.

------=_NextPart_4CA2AA3B_66081D78_10BF1234
Content-Type:text/html;
	charset="utf-8"
Content-Transfer-Encoding:base64
[REDACTED]
------=_NextPart_4CA2AA3B_66081D78_10BF1234--

Expected behavior

Emails should have their sent_at field set as accurately as possible, even when standard headers are missing.

Possible solution

The IMAP protocol provides an INTERNALDATE value for each message, which indicates when the email was received by the server.

Using the internalDate field provided by the imapflow library as a fallback to the Date header could help.

https://imapflow.com/global.html#FetchMessageObject

for await (const msg of client.fetch(searchCriteria, {
  envelope: true,
  source: true,
  bodyStructure: true,
+ internalDate: true,
  uid: true,
})) {
return {
  id: parsedEmail.messageId || msg.uid.toString(),
  threadId: threadId,
  from: mapAddresses(parsedEmail.from),
  to: mapAddresses(parsedEmail.to),
  cc: mapAddresses(parsedEmail.cc),
  bcc: mapAddresses(parsedEmail.bcc),
  subject: parsedEmail.subject || '',
  body: parsedEmail.text || '',
  html: parsedEmail.html || '',
  headers: parsedEmail.headers,
  attachments,
- receivedAt: parsedEmail.date || new Date(),
+ receivedAt: parsedEmail.date || msg.internalDate || new Date(),
  eml: msg.source,
  path: mailboxPath,
};

Screenshots

Note that all these emails have same sent date. They are actually sent in 2018.

Image

System:

  • Open Archiver Version: 0.3.4
*Originally created by @prinsss on 10/14/2025* **Describe the bug** I found that some emails fetched via IMAP have an incorrect value for the `sent_at` field. Many archived emails have the time when they are fetched as their `Sent` date. It seems that we are currently setting the `sent_at` field of an email by parsing its raw content with `mailparser` and reading the `Date` header (see [ImapConnector.ts](https://github.com/LogicLabs-OU/OpenArchiver/blob/1e048fdbc1d0e60b35a6c633309acd14927a6824/packages/backend/src/services/ingestion-connectors/ImapConnector.ts#L294) and [mail-parser.js](https://github.com/nodemailer/mailparser/blob/2328e1c9c79e25ac67636081b2d507e119163f77/lib/mail-parser.js#L805)). However, not all emails contain a `Date` header. In some cases, even the `Received` header may be absent. This results in fallback to `new Date()`, causing inaccurate timestamps. **To Reproduce** Steps to reproduce the behavior: 1. Fetch emails from an IMAP mailbox that contains messages without a `Date` header. 2. Observe that the `sent_at` field for these emails is set to the current time, not the true received time. <details> <summary>👉 Example .eml file</summary> It seems that all emails sent from this address have no Date header. :( ``` X-QQ-ACTION: no-bounce X-QQ-mid: newapiserver5t1601234588t12345 X-QQ-INNER-SUBJECT: X-QQ-INNER-SUBJECT-ID: -12345 X-QQ-INNER-PENDING: 1 X-QQ-SSF: 0000000000000000000000000000000 X-QQ-STYLE: 4 From:"=?utf-8?B?6IW+6K6v5LqR?=" <cloud_noreply@tencent.com> To: user@example.com Subject:=?utf-8?B?5YWz5LqOQ09T5om56YeP5aSE55CG5Y2z5bCG57uT5p2f5YWs5rWL55qE6YCa55+l?= Content-Type: multipart/alternative; boundary="----=_NextPart_4CA2AA3B_66081D78_10BF1234" Content-Transfer-Encoding:base64 This is a multi-part message in MIME format. ------=_NextPart_4CA2AA3B_66081D78_10BF1234 Content-Type:text/html; charset="utf-8" Content-Transfer-Encoding:base64 [REDACTED] ------=_NextPart_4CA2AA3B_66081D78_10BF1234-- ``` </details> **Expected behavior** Emails should have their `sent_at` field set as accurately as possible, even when standard headers are missing. **Possible solution** The IMAP protocol provides an `INTERNALDATE` value for each message, which indicates when the email was received by the server. Using the `internalDate` field provided by the `imapflow` library as a fallback to the `Date` header could help. https://imapflow.com/global.html#FetchMessageObject ```diff for await (const msg of client.fetch(searchCriteria, { envelope: true, source: true, bodyStructure: true, + internalDate: true, uid: true, })) { ``` ```diff return { id: parsedEmail.messageId || msg.uid.toString(), threadId: threadId, from: mapAddresses(parsedEmail.from), to: mapAddresses(parsedEmail.to), cc: mapAddresses(parsedEmail.cc), bcc: mapAddresses(parsedEmail.bcc), subject: parsedEmail.subject || '', body: parsedEmail.text || '', html: parsedEmail.html || '', headers: parsedEmail.headers, attachments, - receivedAt: parsedEmail.date || new Date(), + receivedAt: parsedEmail.date || msg.internalDate || new Date(), eml: msg.source, path: mailboxPath, }; ``` **Screenshots** Note that all these emails have same sent date. They are actually sent in 2018. <img width="1834" height="941" alt="Image" src="https://github.com/user-attachments/assets/35b4d1d4-cad3-439b-88ce-2671b9c48771" /> **System:** - Open Archiver Version: 0.3.4
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/OpenArchiver#155