Skip to content

User activityFile accessNetwork

Apple Mail: Envelope Index and EMLX on macOS

Apple Mail keeps message metadata in the Envelope Index SQLite database and each message as an .emlx file, showing email sent, received and opened.

Location
~/Library/Mail/V10/MailData/Envelope Index
Proves
Which emails were sent or received, from and to whom, when, in which mailbox, and which attachments were opened
Timestamps
Envelope Index dates in Unix epoch seconds (UTC); message headers in RFC 5322 local time
Access
TCC-protected (Mail data): Full Disk Access for the collector
Retention
Until deleted or removed from the server; local copies follow account sync settings
Collection
Disk image, ditto

What it is

Apple Mail stores each message as a separate .emlx file inside per-account mailbox bundles, and indexes all of them in a SQLite database named Envelope Index (no file extension). The index holds one row per message with sender, subject, dates, mailbox and flags, which makes it the fastest way to build an email timeline. The .emlx files hold the full raw message, including headers, body and (when downloaded) attachments.

The data lives in a versioned folder, ~/Library/Mail/V<n>/, whose number changes with major Mail releases.

Where it lives

macOSMail folder
11 Big Sur~/Library/Mail/V8/
12 Monterey~/Library/Mail/V9/
13 Ventura and later~/Library/Mail/V10/
ItemPath
Envelope Index~/Library/Mail/V<n>/MailData/Envelope Index (+ -wal, -shm)
Accounts~/Library/Mail/V<n>/<account UUID>/
Messages.../<Mailbox>.mbox/<UUID>/Data/<digits>/Messages/<ROWID>.emlx
Partial downloads<ROWID>.partial.emlx next to the above
Opened attachments~/Library/Containers/com.apple.mail/Data/Library/Mail Downloads/

~/Library/Mail and the Mail container are protected by macOS privacy controls since Mojave: the collecting process needs Full Disk Access. After upgrades or migrations, older V<n> folders can remain; the active one is normally the highest number with recent modification times, but examine all of them.

What it proves

  • Messages present in each mailbox, with sender, subject, sent and received times, read, flagged and deleted state.
  • Recipients (To and Cc) through the recipients table.
  • Which accounts were configured (mailbox URLs carry the account UUID and scheme such as imap:// or local://).
  • Attachments the user opened from Mail, through copies in Mail Downloads.
  • Full message content and headers (including Received: chains and Message-ID) from .emlx.

It does not prove the user read a message just because read is set (rules, other devices and server sync can set flags), and it cannot show messages that were never downloaded to this Mac.

Key fields

Envelope Index (column names as seen on V10; check .schema on older versions):

TableColumnsMeaning
messagesROWID, sender, subject, date_sent, date_received, mailbox, read, flagged, deleted, conversation_id, global_message_id, remote_id, date_last_viewedOne row per message; sender, subject, mailbox are foreign keys
subjectsROWID, subjectDeduplicated subjects
addressesROWID, address, commentEmail address and display name
recipientsmessage, address, type, positionRecipients per message
mailboxesROWID, url, total_count, unread_countMailbox URL per account
message_global_dataROWID, message_id_headerRFC Message-ID
attachmentsmessage, attachment_id, ...Attachment records

.emlx layout: a first line with the byte length of the message, then the raw RFC 822 / MIME message, then an XML property list with Mail metadata such as flags, date-received, date-last-viewed, conversation-id and remote-id (observed on V10).

The ROWID in messages is also the .emlx file name, which links index rows to files.

Timestamps

  • date_sent and date_received in the Envelope Index are Unix epoch seconds (UTC), not Mac absolute time. Adding 978307200 shifts them 31 years into the future, a known mistake.
  • .emlx headers carry the sender's Date: in their own time zone, and Received: headers carry server times.
  • File system times on .emlx files show when Mail wrote them locally.
SELECT datetime(date_received, 'unixepoch') AS received_utc FROM messages LIMIT 5;

Retention

Messages stay until the user deletes them and the deletion is purged, or until the server copy is removed and Mail syncs. Trash and junk handling follow per-account settings. Attachment copies in Mail Downloads persist until removed. An Envelope Index rebuild (Mail rebuilds it when damaged) reindexes from the .emlx store, so rows for files already gone will not reappear.

Collection

# Terminal with Full Disk Access; quit Mail first if possible
mkdir -p case/mail
ditto ~/Library/Mail case/mail/Mail
ditto ~/Library/Containers/com.apple.mail/Data/Library/Mail\ Downloads case/mail/MailDownloads
shasum -a 256 case/mail/Mail/V*/MailData/Envelope\ Index*
  • Mail can hold tens of gigabytes; a Data volume image is often more practical than a logical copy.
  • Copy the -wal and -shm files with Envelope Index.

Parsing

  • sqlite3 against a copy of the index:
SELECT datetime(m.date_received, 'unixepoch') AS received_utc,
       datetime(m.date_sent, 'unixepoch')     AS sent_utc,
       a.address AS sender, a.comment AS sender_name,
       s.subject, mb.url AS mailbox, m.read, m.deleted, m.ROWID
FROM messages m
LEFT JOIN addresses a  ON a.ROWID = m.sender
LEFT JOIN subjects s   ON s.ROWID = m.subject
LEFT JOIN mailboxes mb ON mb.ROWID = m.mailbox
ORDER BY m.date_received;
  • Locate the file for a row: find case/mail/Mail/V10 -name '<ROWID>.emlx' -o -name '<ROWID>.partial.emlx'.
  • emlx (Python) parses .emlx into headers, body and the Apple plist. Stripping the first line also gives a standard .eml for any mail viewer.

Investigator tips

  • Mailbox URLs are percent-encoded (Sent%20Messages); decode them before reporting.
  • Mail sets the quarantine attribute on attachments it saves; read it on files in Mail Downloads and look for a matching QuarantineEventsV2 entry to show when an attachment left Mail. See quarantine events and Gatekeeper.
  • Rows with no matching .emlx are messages whose bodies were never downloaded or were removed from disk.
  • Spotlight indexes .emlx files, which gives a second, independent view of mail metadata to compare with the Envelope Index.
  • Compare new-mail notifications and Messages for a combined communications timeline.
  • Phishing cases: extract Received: and authentication headers from the .emlx, not from the index, which does not store them.

See also