Microsoft 365

Message trace in Exchange Online: the new EAC and Get-MessageTraceV2

Trace a missing email with the new message trace in the Exchange admin center, Get-MessageTraceV2, the Graph message trace API and historical searches.

11 min read
On this page

To trace a missing email in Exchange Online today, open the Exchange admin center at Mail flow > Message trace, select Start a trace, and filter by sender, recipient or Message ID over a range of 10 days or less to get instant results. In PowerShell, use Get-MessageTraceV2 and pipe the result to Get-MessageTraceDetailV2 for the event-by-event history; the legacy Get-MessageTrace cmdlets were deprecated in September 2025. Both tools search the last 90 days, 10 days per query.

Who this is for and what you will have

This guide is for Exchange Online administrators and help desk staff who answer "I never got that email" tickets, and for anyone whose scripts still call Get-MessageTrace. At the end you will have:

  • A repeatable way to find a message in the new EAC message trace and read its events.
  • PowerShell commands that work within the V2 limits, including retrieving more than 5,000 results.
  • A clear idea of when to use a downloadable report, a historical search or the Microsoft Graph API.
  • A list of common reasons a trace comes back empty or incomplete.

What changed in message trace

Microsoft rebuilt message trace and made the new version generally available in mid-2025. According to Microsoft 365 message center post MC1092458:

  • The new experience replaces the legacy one in the EAC at Mail flow > Message trace.
  • The new cmdlets are Get-MessageTraceV2 and Get-MessageTraceDetailV2.
  • The legacy EAC experience and the Get-MessageTrace and Get-MessageTraceDetail cmdlets were deprecated starting September 1, 2025.
  • Message trace support in the Reporting Web Service was scheduled to begin deprecating on March 18, 2026, and users of that service were told to move to the new cmdlets. Since then Microsoft has also published a Microsoft Graph message trace API, described later in this guide, which is the other option for integrations.

The main differences you notice in scripts are summarized here:

AreaBehavior in V2
Search windowLast 90 days; 10 days of data per query
Default rangeLast 48 hours if you don't specify dates
Results per query1,000 by default, up to 5,000 with -ResultSize
PagingNot supported; -PageSize and -Page are gone
Throttling100 query requests per tenant in a rolling 5-minute window
Time stampsOutput is in UTC
ModuleExchangeOnlineManagement 3.7.0 or later

Prerequisites

  • Membership in the Organization Management role group in Exchange Online, or the Exchange Administrator role in Microsoft Entra ID. Microsoft recommends against using Global Administrator for this.
  • The ExchangeOnlineManagement module, version 3.7.0 or later, for the V2 cmdlets.
  • From the user: the sender address, recipient address, approximate send time and, ideally, the Message-ID header of the message (or of the NDR they received).

Check your module version before you start:

Get-Module ExchangeOnlineManagement -ListAvailable | Format-Table Name,Version
Update-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com

Trace a message in the Exchange admin center

Start the trace

  1. In the EAC at https://admin.exchange.microsoft.com, go to Mail flow > Message trace.
  2. Select Start a trace. The defaults search all senders and all recipients for the last two days.
  3. Fill in Senders and Recipients. You can type external addresses, use a single wildcard such as *@fabrikam.com, or paste a list separated by semicolons, spaces or new lines.
  4. Set the Time range. The Slider view saves a relative range when you save the query; Custom time range lets you choose a time zone and exact start and end times.
  5. Open Detailed search options if you need them:
    • Subject filter with starts with, ends with or contains.
    • Delivery status: All, Delivered, Expanded, Failed, Pending, Recalled, Quarantined, Filtered as spam or Getting status. Pending, Quarantined and Filtered as spam are only available for searches shorter than 10 days.
    • Message ID, which must include the angle brackets, for example <d9683b4c-127b-413a-ae2e-fa7dfb32c69d@contoso.com>.
    • Network Message ID, the value that persists across copies of the message created by bifurcation. You can read it from headers such as X-MS-Exchange-Organization-Network-Message-Id.
    • Direction: All, Inbound or Outbound.
    • Original client IP address.
  6. Choose a report type and select Search (or Next for downloadable reports).

The Message trace page also keeps Default queries, Custom queries your admins saved, and Autosaved queries with the last 10 queries you ran.

Choose the right report type

Report typeWhen it's availableMaximum resultsDelivery
Summary reportTime range of 10 days or less20,000Instant, in the browser
Enhanced summary reportAny range up to 90 days; needs a sender, recipient or Message ID filter100,000Downloadable CSV, can take hours
Extended reportAny range up to 90 days; needs a sender, recipient or Message ID filter1,000Downloadable CSV with routing and event detail

If your range is even slightly longer than 10 days, the results are only available as a downloadable CSV prepared from archived data, and the last 24 hours of archived data typically aren't included. Downloadable reports appear on the Downloadable reports tab with the status Not started, In progress or Complete, and a notification goes to an address in one of your accepted domains. A CSV larger than 800 MB can't be opened in Excel or Notepad, so narrow the filters rather than widening the range.

The Original client IP address is only included in the Enhanced summary and Extended reports, and only for 10 days.

Read the result

The summary report lists Date, Sender, Recipient, Subject and Status, newest first. The first 250 rows load immediately and more load as you scroll, up to 10,000. A distribution group recipient appears first, followed by each member on its own line.

Select a row to open the details flyout. The Message events section is where the answer usually is:

EventMeaning
ReceiveThe service received the message
SendThe service sent the message onward, for example to an external server
DeliverThe message was delivered to a mailbox
FailDelivery failed
DeferDelivery was postponed and might be retried
ExpandA distribution group was expanded
TransferRecipients were moved to a bifurcated copy
ResolvedThe recipient was redirected to a new address based on a directory lookup
DLP ruleA data loss prevention rule matched

The More information section shows the Message ID, message size, From IP (blank for outbound mail sent from Exchange Online) and To IP (blank for inbound mail). If a message shows as Quarantined, continue with the quarantine workflow in quarantine policies in Defender for Office 365.

Trace with Get-MessageTraceV2

Basic queries

Messages from one sender over two days:

Get-MessageTraceV2 -SenderAddress john@contoso.com -StartDate 10/09/2026 -EndDate 10/11/2026

Dates use the short date format of the computer you run the command on; the examples here assume MM/dd/yyyy. To include a time, quote the value, for example "10/09/2026 5:00 PM". Remember that the output time stamps are in UTC.

A specific message by its Message ID, with the full event history:

Get-MessageTraceV2 -MessageId "<d9683b4c-127b-413a-ae2e-fa7dfb32c69d@contoso.com>" -StartDate 10/04/2026 -EndDate 10/11/2026 |
    Get-MessageTraceDetailV2

Only failed or quarantined messages to one recipient:

Get-MessageTraceV2 -RecipientAddress alina@contoso.com -Status Failed,Quarantined -StartDate 10/01/2026 -EndDate 10/11/2026

Other filters include -FromIP, -ToIP, -Subject with -SubjectFilterType (Contains, StartsWith or EndsWith; Microsoft recommends the last two over Contains) and -MessageTraceId, the network message ID GUID. Microsoft says MessageTraceId is required to get complete results for a message sent to more than 1,000 recipients.

Detail queries

Get-MessageTraceDetailV2 requires -MessageTraceId and -RecipientAddress. You can supply them by piping from Get-MessageTraceV2, as above, or directly:

Get-MessageTraceDetailV2 -MessageTraceId ae5c1219-4c90-41bf-fef5-08d837917e7c -RecipientAddress robert@contoso.com

Use -Event to filter by events such as RECEIVE, SEND, FAIL, DELIVER, EXPAND, TRANSFER or DEFER.

Retrieving more than 5,000 results

V2 has no paging. Results are ordered by Received (newest first) and then by RecipientAddress. To get the next batch, run the same query with EndDate set to the Received value of the last row and StartingRecipientAddress set to its recipient address. This loop follows Microsoft's documented pattern:

$params = @{
    SenderAddress = 'noreply@contoso.com'
    StartDate     = (Get-Date).AddDays(-7)
    EndDate       = Get-Date
    ResultSize    = 5000
}
$all = @()
do {
    $batch = @(Get-MessageTraceV2 @params)
    $all += $batch
    if ($batch.Count -eq $params.ResultSize) {
        $params.EndDate = $batch[-1].Received.ToString('O')
        $params.StartingRecipientAddress = $batch[-1].RecipientAddress
        Start-Sleep -Seconds 5
    }
} while ($batch.Count -eq $params.ResultSize)
$all | Export-Csv .\trace.csv -NoTypeInformation

Keep the date range itself at 10 days or less, and remember that every iteration counts against the 100-requests-per-5-minutes tenant limit. Shared automation, monitoring tools and other admins all draw from the same quota.

Other ways to get message trace data

For a CSV of up to 100,000 rows from the last 90 days, without staying within the 10-day window, use a historical search. You must specify at least one of MessageID, RecipientAddress or SenderAddress:

Start-HistoricalSearch -ReportTitle "Fabrikam invoices" -StartDate 07/15/2026 -EndDate 10/10/2026 `
  -ReportType MessageTrace -SenderAddress billing@fabrikam.com -NotifyAddress admin@contoso.com

Historical searches cover messages between about 1 to 4 hours and 90 days old, and you can submit up to 250 in 24 hours (cancelled searches count). If you search for a distribution group as the recipient, not all messages might be returned; search for the individual recipient instead. When the search completes, a notification goes to the NotifyAddress mailbox, which must be in one of your accepted domains.

Microsoft Graph message trace API

For applications and SIEM integrations, Microsoft Graph exposes message trace at GET /admin/exchange/tracing/messageTraces, with the ExchangeMessageTrace.Read.All permission. It follows the same rules as the cmdlets: 90 days, 10 days per query, 48 hours by default, $top from 1 to 5,000 and 100 requests per 5 minutes. Unlike the cmdlet, it does support paging through @odata.nextLink. Before the first call you must create a service principal in your tenant for the application ID 8bd644d1-64a1-4d4b-ae52-2e0cbf64e373:

Connect-MgGraph -Scopes "Application.ReadWrite.All"
New-MgServicePrincipal -BodyParameter @{ appId = "8bd644d1-64a1-4d4b-ae52-2e0cbf64e373" }

Provisioning can take several hours, and requests fail with 401 (Unauthorized) until it completes. At the time of writing the v1.0 endpoint is listed for the global service only, not the US Government or China clouds.

Troubleshooting

An old script still calls the legacy cmdlets. Get-MessageTrace and Get-MessageTraceDetail are deprecated. Replace them with the V2 cmdlets, replace -PageSize with -ResultSize, and replace page loops with the StartingRecipientAddress pattern above.

The trace is empty for a message that was just sent. Recently received messages show Getting status until more data is available, and Microsoft notes a five to ten minute delay between actual and reported status. Wait and search again.

The time looks wrong or the message seems missing. PowerShell output is in UTC, while the EAC uses the time zone from your Exchange account settings. Widen the range by a few hours on each side.

A Message ID search finds nothing. Include the full value with the angle brackets and enclose it in quotation marks. Message IDs created by other mail systems can use different formats.

The query fails because the date range is too long. Each query can cover only 10 days. Split the range, or use a downloadable report or Start-HistoricalSearch.

Graph returns "Your recent queries have surpassed the permitted limit, please try again later." You exceeded 100 requests in 5 minutes. Add a delay between calls and narrow the filters so fewer requests are needed.

The message was rejected with a 5.4.1 NDR. The recipient address isn't in your directory; see fix 550 5.4.1 Recipient address rejected.

Checklist

  • ExchangeOnlineManagement 3.7.0 or later installed on every admin workstation and automation host.
  • Scripts migrated from Get-MessageTrace to Get-MessageTraceV2 and from -PageSize to -ResultSize.
  • Queries kept to 10 days and to as narrow a filter as possible.
  • Large exports use the EndDate plus StartingRecipientAddress loop and stay under 100 requests per 5 minutes.
  • Help desk knows how to ask users for the Message-ID header.
  • Integrations that used the Reporting Web Service moved to the V2 cmdlets or to the Graph message trace API, with the service principal provisioned.

References

Questions people ask

Is Get-MessageTrace still supported in Exchange Online?

No. Microsoft deprecated the legacy Get-MessageTrace and Get-MessageTraceDetail cmdlets starting September 1, 2025. Use Get-MessageTraceV2 and Get-MessageTraceDetailV2, which require version 3.7.0 or later of the Exchange Online PowerShell module.

How far back can message trace search in Exchange Online?

Message trace covers the last 90 days, but each query can cover at most 10 days. In the Exchange admin center, a range longer than 10 days produces a downloadable report instead of instant results.

How do I get more than 5000 results from Get-MessageTraceV2?

The cmdlet has no paging. Run the query again with EndDate set to the Received time of the last result and StartingRecipientAddress set to its recipient address, and repeat until no new rows come back.

Why does message trace return nothing for a message I just sent?

Recent messages can show the status Getting status, and Microsoft notes a five to ten minute delay between actual and reported delivery status. Also check that your date range is in the right time zone, because PowerShell output timestamps are in UTC.

Exchange OnlineMessage traceExchange Online PowerShellExchange admin center
  1. Tenant External Recipient Rate Limit (TERRL): monitor it and fix 5.7.233

    How the Exchange Online tenant-wide external recipient limit is calculated after the 2026 changes, how to monitor it in the EAC and PowerShell, and what to do when users get 550 5.7.233.

    Microsoft 36510 min read
  2. Calendar permissions in Exchange Online: Add-MailboxFolderPermission guide

    Share calendars, change the organization-wide Default permission and add calendar delegates in Exchange Online with Add-, Set- and Remove-MailboxFolderPermission, including localized folder names.

    Microsoft 3659 min read
  3. Convert a user mailbox to a shared mailbox and remove the license safely

    Keep a leaver's email and calendar in Exchange Online without paying for a license: secure the account, convert the mailbox, grant access, then remove the license in the right order.

    Microsoft 36511 min read