oeltayeb.com · Exchange Online Toolkit

Checklist

Email never arrived? Using message trace in Exchange Online to find out why

Based on the article: Email never arrived? Using message trace in Exchange Online to find out why · 5 min read

"I never got that email" is a classic helpdesk ticket, and guessing wastes everyone's time. Message trace shows whether Exchange Online received a message, what it did with it and where it ended up. In this post I'll walk through tracing in the Exchange admin center and with the V2 PowerShell cmdlets, how to read the results, and what to do next for each outcome.

Before you start

Traces covering 10 days or less return results almost immediately.

  • Permissions: the Exchange Administrator role in Microsoft Entra ID, or membership of the Organization Management role group in Exchange Online.
  • Facts from the user: sender, recipient, roughly when it was sent (and in which time zone) and the subject. If anyone has a copy, the Message-ID from the headers is the most precise filter there is.
  • For PowerShell: the ExchangeOnlineManagement module, version 3.7.0 or later.

Checklist

  1. 1

    Run a trace in the Exchange admin center

    • In the Exchange admin center (admin.exchange.microsoft.com), go to Mail flow › Message trace. The Exchange message trace link in the Microsoft Defender portal opens the same page.
    • Select Start a trace. The defaults search all senders and recipients for the last two days.
    • Enter the Senders and/or Recipients. External addresses work, and so does one wildcard per value, such as *@fabrikam.com.
    • Set the Time range. Switch to Custom time range to pick a time zone and exact start and end times.
    • Under Detailed search options, narrow it with a subject filter (starts with, ends with or contains), a delivery status, the Message ID (including the angle brackets) or the direction.

    +1 more in the full article.

  2. 2

    Read the delivery status

    StatusWhat it meansNext step
    DeliveredHanded to the mailbox or the recipient's mail serverMail flow worked. Check Junk Email, Inbox rules and the Other tab.
    FailedNot deliveredOpen the details; the Fail event carries the reason and NDR code.
    PendingDelivery is being attempted or retriedLook at the Defer events and the To IP; usually a receiving-side problem.
    QuarantinedHeld as spam, bulk or phishingReview it on the Quarantine page of the Microsoft Defender portal.
    Filtered as spamIdentified as spam and rejected or blocked, not quarantinedCheck the verdict in the details and which anti-spam policy applied.
    ExpandedA group was expanded to its membersTrace the individual members.
    Getting statusReceived moments ago, no data yetWait a few minutes and refresh.

    You may also see Recalled when the sender used Message Recall. Two caveats: you can only filter on Pending, Quarantined and Filtered as spam in searches shorter than 10 days, and the reported status can trail reality by five to ten minutes.

  3. 3

    Open the message trace details

    Click a row (not its round check box) to open the details. Expand Message events and read them in order: Receive first, then any processing, ending in Deliver, Send, Fail or Defer.

  4. 4

    Trace from PowerShell with the V2 cmdlets

    Get-MessageTraceV2 and Get-MessageTraceDetailV2 replace Get-MessageTrace and Get-MessageTraceDetail, which Microsoft is retiring, so update any old scripts. The rules have changed:

    • Data goes back 90 days, but one query can span at most 10 days. Without dates you get the last 48 hours.
    • Results default to 1,000 rows and -ResultSize goes up to 5,000. -Page and -PageSize are gone.
    • Timestamps are in UTC, and a tenant can run 100 queries in any five-minute window.
    powershell
    Connect-ExchangeOnline
    
    # Failed messages to one recipient in the last 24 hours
    $trace = Get-MessageTraceV2 -RecipientAddress user@contoso.com -Status Failed `
        -StartDate (Get-Date).AddDays(-1) -EndDate (Get-Date)
    $trace | Format-Table Received, SenderAddress, Subject, Status
    
    # Event-by-event detail for the same messages
    $trace | Get-MessageTraceDetailV2 | Format-List
  5. 5

    Go further back with downloadable reports

    For ranges longer than 10 days, or when you need more detail, the admin center builds two CSV reports from archived trace data: the Enhanced summary report (adds direction, original client IP and connector) and the Extended report (full routing and event detail). Both need at least a sender, recipient or Message ID.

    In PowerShell, the equivalent is a historical search, which covers messages up to 90 days old:

    powershell
    Start-HistoricalSearch -ReportTitle "Partner invoices" -ReportType MessageTraceDetail `
        -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date).AddDays(-12) `
        -SenderAddress billing@fabrikam.com -NotifyAddress admin@contoso.com
    
    Get-HistoricalSearch | Format-Table ReportTitle, Status, Rows

Verify

  • No record at all: the message never reached Exchange Online. Recheck the address spelling, time range and time zone, confirm your MX record and connectors, then ask the sender's admin for their outbound logs.
  • Delivered but not visible: look at Junk Email, Inbox rules, Focused Inbox and any auto-delete or retention settings. Message trace can't see what happens after delivery.
  • Failed: the NDR code in the Fail event is your starting point.
  • Quarantined or Filtered as spam: decide whether it's a false positive, release it if appropriate and submit it to Microsoft for review.
  • Pending for hours: the receiving server is deferring. If retries eventually run out, the sender gets an NDR.

Tips & gotchas

  • The admin center shows times in the time zone from your Exchange account settings, while PowerShell returns UTC. Mixing the two up is an easy way to search the wrong window.
  • For a message sent to more than 1,000 recipients, filter by -MessageTraceId to get complete results.
  • Prefer -SubjectFilterType StartsWith or EndsWith over Contains; Microsoft recommends them for performance.
  • Historical searches are capped at 250 per tenant in 24 hours, and cancelled ones still count.

Microsoft Learn references