Common Causes of Mail Loops and How to Fix Them
How to systematically identify and fix SMTP mail loops in Exchange Online, hybrid environments, and upstream mail gateways using NDRs, headers, Message Trace, recipient objects, and connectors.
A mail loop occurs when at least two transport systems repeatedly hand the same message back and forth. Neither system recognizes itself as the final destination, but both know an ostensibly suitable next hop. The loop ends only when a server determines that the permitted number of transport hops has been exceeded and generates an NDR.
In Exchange, two messages are particularly informative:
554 5.4.6 Hop count exceeded - possible mail loopis typically generated by local Exchange.554 5.4.14 Hop count exceeded - possible mail loop ATTR34is generated by Exchange Online.
The hop limit is not the cause, but rather the safeguard against endless repetition. Increasing it therefore fixes nothing. The goal is to find the point at which the message is returned to a system it has already passed through, contrary to the intended destination architecture.
Recognizing the loop pattern in the header
The NDR and the complete original message headers should be saved before making any changes. Received lines are read from bottom to top: the bottom line is the earliest documented hop, and the top line is the most recent.
A loop usually appears as a recurring sequence:
Internet
→ Exchange Online Protection
→ Mailgateway
→ Exchange Online Protection
→ Mailgateway
→ Exchange Online Protection
→ ...
Not every Microsoft hostname that appears multiple times is necessarily a loop. Exchange Online processes messages internally through multiple transport roles. What stands out is a repeated return between the same administrative boundaries, for example between Exchange Online and a local gateway. Timestamps, sending IP address, receiving host, and Message-ID help identify the cycle unambiguously.
For the initial analysis, answer these questions:
- Which system generated the NDR?
- Which two or three hops repeat?
- Which system should have delivered the message definitively?
- Based on which domain, recipient, connector, or rule decision was it forwarded?
- What change most recently affected mail flow?
Diagnosis in Exchange Online
With Get-MessageTraceV2, you can examine processing from the last 90 days; each query is limited to a maximum of ten days. A narrow time window and the specific recipient address provide the most useful results:
$start = (Get-Date).AddHours(-2)
$end = Get-Date
$recipient = "user01@contoso.com"
$trace = Get-MessageTraceV2 `
-RecipientAddress $recipient `
-StartDate $start `
-EndDate $end `
-ResultSize 5000
$trace |
Select-Object Received,SenderAddress,RecipientAddress,Subject,
Status,FromIP,ToIP,MessageTraceId,MessageId |
Sort-Object Received
The details of a result show individual transport events:
$trace | ForEach-Object {
Get-MessageTraceDetailV2 `
-MessageTraceId $_.MessageTraceId `
-RecipientAddress $_.RecipientAddress
} | Format-Table Date,Event,Action,Detail -AutoSize
Next, review the domain, recipient, and connectors together:
Get-AcceptedDomain |
Format-Table Name,DomainName,DomainType,MatchSubDomains -AutoSize
Get-EXORecipient -Identity $recipient |
Format-List DisplayName,RecipientTypeDetails,PrimarySmtpAddress,
ExternalEmailAddress,EmailAddresses
Get-OutboundConnector -IncludeTestModeConnectors |
Format-List Name,Enabled,ConnectorType,RecipientDomains,SmartHosts,
UseMXRecord,RouteAllMessagesViaOnPremises,TlsSettings
Get-InboundConnector |
Format-List Name,Enabled,ConnectorType,SenderDomains,SenderIPAddresses,
TlsSenderCertificateName,RequireTls,RestrictDomainsToIPAddresses,
RestrictDomainsToCertificate
What matters is not whether an individual object appears plausible. The domain type, actual recipient type, and applicable connector must all describe the same destination.
Diagnosis in local Exchange
In a hybrid environment, check the same recipient locally as well. The queries distinguish between an actual local mailbox, a RemoteMailbox, and a MailUser:
Get-Recipient -Identity $recipient |
Format-List DisplayName,RecipientType,RecipientTypeDetails,
PrimarySmtpAddress,EmailAddresses
Get-Mailbox -Identity $recipient -ErrorAction SilentlyContinue |
Format-List RecipientTypeDetails,ServerName,Database,PrimarySmtpAddress
Get-RemoteMailbox -Identity $recipient -ErrorAction SilentlyContinue |
Format-List RecipientTypeDetails,PrimarySmtpAddress,RemoteRoutingAddress
Get-MailUser -Identity $recipient -ErrorAction SilentlyContinue |
Format-List RecipientTypeDetails,PrimarySmtpAddress,ExternalEmailAddress
For the transport path, you need Send and Receive connectors as well as the tracking logs:
Get-SendConnector |
Format-List Name,Enabled,AddressSpaces,DNSRoutingEnabled,SmartHosts,
SourceTransportServers,CloudServicesMailEnabled,TlsDomain
Get-ReceiveConnector |
Format-List Identity,Enabled,Bindings,RemoteIPRanges,PermissionGroups
$servers = Get-ExchangeServer |
Where-Object { $_.IsMailboxServer -or $_.IsHubTransportServer }
$servers |
Get-MessageTrackingLog `
-Start $start `
-End $end `
-Recipients $recipient `
-ResultSize Unlimited |
Select-Object Timestamp,ServerHostname,ClientHostname,Source,EventId,
ConnectorId,Sender,Recipients,MessageId,NetworkMessageId |
Sort-Object Timestamp
An SEND to Exchange Online followed by another RECEIVE of the same message from Exchange Online makes the return path visible. MessageId and NetworkMessageId help prevent different test messages from being confused with each other.
Overview of the most common causes
| Pattern | Typical cause | Resolution |
|---|---|---|
| Unknown recipients bounce between two systems | Accepted Domain is set to InternalRelay, but both sides forward unknown recipients | Define clear responsibility; for complete EXO delivery, use Authoritative, or for a split domain, define a single final hop |
| EXO sends to local Exchange, which immediately returns it to EXO | Hybrid connector or Centralized Mail Transport no longer matches the mailbox location | Check HCW configuration and RouteAllMessagesViaOnPremises; disable obsolete centralized routing or correct local recipient resolution |
| Message bounces between EXO and a security, signature, or encryption gateway | Returning messages meet the outbound rule again | Use the header set by the gateway or its documented loop-prevention mechanism as an exception; clearly authenticate inbound and outbound connectors |
| Only one recipient is affected | Outdated or incorrect targetAddress, incorrect RemoteMailbox type, or conflicting proxy addresses | Determine the Source of Authority, correct the recipient object there, and synchronize it |
| Only forwarded messages loop | A transport rule, mailbox forwarding, or inbox rule targets the original path again | Disable the rule, correct the destination, and define a robust exception |
| Only a subdomain or application is affected | The parent domain does not correctly cover the subdomain in the expected connector path | Explicitly configure the subdomain as an Accepted Domain and in the appropriate Send Connector |
| All messages loop after a gateway or DNS change | Smart Host or MX points to the inbound side of the sending system | Correct the next hop and separately check DNS, NAT, and load balancer targets |
Cause 1: Incorrect Accepted Domain type
An authoritative domain means that all valid recipients for that domain are known within the Exchange organization; unknown recipients are rejected. An Internal Relay domain means that some recipients are located in another system and must be forwarded through a Send or Outbound Connector.
The problematic configuration occurs when Exchange Online sends unknown recipients to a local system and that system also does not handle the same domain definitively, instead returning it to Exchange Online through MX or a Smart Host.
Get-AcceptedDomain -Identity contoso.com |
Format-List DomainName,DomainType,MatchSubDomains
If all recipients are in Exchange Online after a completed migration, Authoritative is usually the correct target state:
# Run only after fully reviewing recipients and routing.
Set-AcceptedDomain -Identity contoso.com -DomainType Authoritative
For a genuine split domain, InternalRelay may be correct. However, this requires a clear connector to the system that knows the remaining recipients. That destination must not send unknown addresses back to the starting point.
Cause 2: Overlapping hybrid connectors and Centralized Mail Transport
Centralized Mail Transport intentionally routes outgoing Exchange Online messages through local Exchange. This is useful for certain compliance requirements, but it creates additional transport paths. If the option remains enabled after a migration while the local system sends messages back to Exchange Online through its own MX, a loop can result.
Get-OutboundConnector -IncludeTestModeConnectors |
Format-Table Name,Enabled,ConnectorType,RouteAllMessagesViaOnPremises,
RecipientDomains,SmartHosts,UseMXRecord -AutoSize
You should also check multiple connectors with overlapping scopes. Microsoft recommends a dedicated on-premises connector for hybrid mail flow; repairing it through the Hybrid Configuration Wizard is often safer than making isolated individual changes.
If Centralized Mail Transport is demonstrably no longer needed, the setting can be disabled specifically:
# Only after reviewing compliance and gateway requirements.
Set-OutboundConnector `
-Identity "Outbound to On-Premises" `
-RouteAllMessagesViaOnPremises:$false
Cause 3: A gateway reprocesses its returned messages
In an in-and-out scenario, Exchange Online sends a message to an additional service for signing, encryption, or archiving. The service then returns it to Exchange Online. The outbound rule must recognize the returned message; otherwise, it is sent to the service again.
Start by reviewing all rules that select connectors, redirect recipients, or evaluate headers:
Get-TransportRule |
Sort-Object Priority |
Format-List Name,State,Mode,Priority,FromScope,SentToScope,
RedirectMessageTo,RouteMessageOutboundConnector,
SetHeaderName,SetHeaderValue,ExceptIfHeaderContainsMessageHeader,
ExceptIfHeaderContainsWords
The specific exception must follow the gateway vendor’s documentation. A header set by the service that cannot be reliably spoofed by the internet is common. In addition, inbound connectors should identify the service by certificate or fixed sender IP address. A blanket exception for all messages that appear “internal” is too broad.
Cause 4: The recipient object and the actual mailbox are not in the same location
An object can appear in Exchange Online as a MailUser even though the active mailbox is local. In a synchronized hybrid environment, this is not automatically a duplicate. Nor does an ExternalEmailAddress that matches the primary SMTP address alone prove a misconfiguration.
What matters is the combination of all queries:
Get-Mailboxreturns a result locally: The active mailbox is local.Get-RemoteMailboxreturns a result locally: The managed destination is in Exchange Online.Get-EXOMailboxreturns a result: A real mailbox exists in the cloud.Get-EXORecipientreturns only a MailUser: The object is a routing destination, not a cloud mailbox.
Outdated objects after a migration, incorrect remote routing domains, or manually set targetAddress values whose domain routes back through the same transport path are problematic. Make changes at the Source of Authority: in synchronized environments, use Exchange management tools locally rather than directly editing individual attributes in Exchange Online.
Cause 5: Forwarding and transport rules form a loop
A rule can redirect from address A to B, while B sends back to A through a second rule, mailbox forwarding, or an external system. Such loops often affect only individual recipients or message types.
Get-TransportRule |
Sort-Object Priority |
Select-Object Name,State,Mode,Priority,RedirectMessageTo,
BlindCopyTo,AddToRecipients,RouteMessageOutboundConnector
Get-Mailbox -ResultSize Unlimited |
Select-Object DisplayName,PrimarySmtpAddress,
ForwardingAddress,ForwardingSmtpAddress,DeliverToMailboxAndForward
Get-InboxRule -Mailbox user01@contoso.com |
Select-Object Name,Enabled,Priority,ForwardTo,RedirectTo,ForwardAsAttachmentTo
The resolution is not simply to disable a rule temporarily. The complete chain must be broken, and rules for external services need an exception that reliably identifies messages already processed.
Cause 6: MX, Smart Host, or subdomain points back
A gateway may require a different internal next hop than external senders. If it simply uses the public MX for forwarding, that MX may point back to the gateway itself. The same issue occurs when a Smart Host routes back to its own listener through NAT or load balancing.
Resolve-DnsName -Type MX contoso.com
Resolve-DnsName -Type MX app.contoso.com
Get-SendConnector |
Format-List Name,AddressSpaces,DNSRoutingEnabled,SmartHosts
Subdomains deserve separate review. Microsoft documents cases in which an application subdomain must be explicitly created as an Internal Relay domain and synchronized to the Edge systems:
New-AcceptedDomain `
-Name "app.contoso.com" `
-DomainName app.contoso.com `
-DomainType InternalRelay
Start-EdgeSynchronization
These commands are not a universal fix. They apply only if app.contoso.com is actually delivered outside the Exchange organization and the Send Connector has an unambiguous next hop.
Safe approach during an active loop
During the incident, first stop the multiplication of messages. Depending on the architecture, carefully disable the triggering transport rule or specific connector, or have the gateway hold the affected queue. Export the configuration and message samples beforehand.
Then test with exactly one sender, one recipient, and a clearly identifiable subject line. Track the message end to end through headers, Message Trace, and local tracking logs. Reopen mail flow gradually only after it ends at the intended destination.
Not recommended:
- Increasing hop limits
- Changing multiple connectors at the same time
- Switching Accepted Domains between
AuthoritativeandInternalRelayon a hunch - Repeatedly resubmitting a problematic queue without checking it
- Correcting synchronized Exchange attributes directly in AD or Exchange Online
- Disabling TLS, IP, or certificate checks as a supposed quick fix
Final verification
After the correction, documentation should contain exactly one statement for each relevant domain: Which system knows the recipient, which connector applies, and which host is the final next hop?
Technical acceptance includes at least:
- External and internal test messages
- An unknown recipient in the same domain
- A recipient on each side of a genuine split domain
- An outgoing message with the gateway or Centralized Mail Transport enabled
- Headers without a recurring hop sequence
- Message Trace with
Deliveredor the expected handoff - Local tracking without another
RECEIVEafter anSENDto the same destination - Connector validation for all connectors still required
A resolved mail loop is only complete when not only the test email arrives, but unknown recipients and alternative mail-flow paths also terminate as defined. That is precisely where most recurrences occur.
Comments
Comments are loaded from GitHub / Giscus.