You create a mail flow rule (transport rule) in Exchange Server to add a disclaimer, tag external mail or block an attachment, and nothing happens. Or it fires on mail it was never meant to touch. Rules fail quietly, so in this post I'll walk through the checks that find the cause: state and mode, priority and stop processing, how each condition really matches, and how to prove a match with message tracking.
Errors this guide fixes
5.7.1 Delivery not authorized, message refusedNDR (rule rejection, default text)
Symptoms#
- The rule's action never shows up: no disclaimer, no subject prefix, no Bcc copy, no rejection.
- It works for some senders or recipients but not others, for example mail sent to an alias.
- It stopped working after another rule was added or reordered.
- A message is rejected that shouldn't be, and the NDR shows the text Exchange uses when a rule rejects mail without a custom explanation:
5.7.1 Delivery not authorized, message refused5.7.1 is the default enhanced status code for a rule rejection. If you see it, a rule is applying, just to the wrong messages.
Why it happens#
On Mailbox servers, rules are applied in transit by the Transport Rule agent; Edge Transport servers use the Edge Rule agent. Rules act on messages while they move through the transport pipeline, never on items already sitting in a mailbox. The usual causes:
- State, mode or dates. The rule is disabled, still in a test mode (
AuditorAuditAndNotify, shown in the Exchange admin center as Test without Policy Tips and Test with Policy Tips), or outside itsActivationDate/ExpiryDatewindow. - Priority and stop processing. Rules run in priority order, and 0 is the highest. A higher rule that matches the same message and has Stop processing more rules set ends the evaluation. Some actions, such as deleting the message without notifying anyone, also stop later rules.
- Condition logic. Multiple conditions are combined with AND. Multiple values inside one condition are OR. Any single exception cancels the actions.
- Header vs envelope. Sender conditions look at the message header by default (
SenderAddressLocation=Header), not the SMTP envelope. The To/Cc header conditions and the recipient-address word and pattern conditions match only the recipient's primary address, so mail sent to a proxy address slips past. - Content that can't be read. For S/MIME-encrypted messages a rule sees only the envelope headers. Rights-protected messages need transport decryption before content conditions work. Attachment pattern matching scans only the first 150 KB of each attachment.
- Directory data. Conditions based on Active Directory properties work only for senders and recipients inside the organization. Group membership comes from a cache that expires every four hours by default, so a user you just added to a group isn't matched yet.
- Where the rule lives. Mailbox server rules are stored in Active Directory and need domain controller replication. Edge Transport rules are stored per server in AD LDS and aren't replicated. In hybrid, on-premises rules are never copied to Exchange Online.
- Errors during evaluation. With the default
RuleErrorActionofIgnore, a rule that can't finish processing a message is skipped silently.
How to fix it#
- Read the rule list in priority order. In the Exchange Management Shell:
ThePowerShell
Get-TransportRule | Sort-Object Priority | Format-Table Priority, Name, State, Mode, StopRuleProcessing -AutoSize Get-TransportRule "Tag external mail" | Format-List Name, State, Mode, Priority, ActivationDate, ExpiryDate, RuleErrorAction, SenderAddressLocation, DescriptionDescriptionproperty spells out the conditions, exceptions and actions in plain words. Read it the way Exchange does: every condition must match, any exception wins. - Enable and enforce it.
PowerShell
Enable-TransportRule "Tag external mail" Set-TransportRule "Tag external mail" -Mode Enforce - Fix the order. Look above your rule for any rule with
StopRuleProcessingset toTruewhose conditions could also match the same message. Either move your rule above it, or narrow the other rule:PowerShellSet-TransportRule "Tag external mail" -Priority 0 - Match what the sender really uses. If a gateway, application or relay sets a different envelope sender than the From header, make the rule check both:
For recipients, make sure the address in the condition is the primary SMTP address, or match on the recipient object or a group instead of typed text.PowerShell
Set-TransportRule "Block finance spoof" -SenderAddressLocation HeaderOrEnvelope - Allow for caches and replication. After changing a rule, give Active Directory replication time to finish. For group-based conditions, either wait for the expanded groups cache to refresh or restart the Transport service on each Mailbox server that has to see the change straight away (
Restart-Service MSExchangeTransport), ideally after hours. - Put the rule where the mail flows. On Edge Transport servers, create the rule on every Edge server, or use
Export-TransportRuleCollectionandImport-TransportRuleCollection. Note that importing a collection replaces the rules already on the target, so export them first. In hybrid, create a matching rule in Exchange Online for mail that never passes through your on-premises servers, and check that every condition and action you need exists there. - Handle protected content. For rights-protected mail, check
Get-IRMConfiguration | Format-List TransportDecryptionSetting. Content conditions can't work on S/MIME-encrypted messages at all, so base those rules on sender, recipient or header conditions instead.
Verify the fix#
Test safely first: set a new rule to Audit mode and add a Generate incident report and send it to action, so you get a report for every match without changing delivery. Then send a test message with a unique subject and read the agent data that message tracking recorded for it on all transport servers:
$rule = Get-TransportRule "Tag external mail"
$hits = Get-TransportService | ForEach-Object {
Get-MessageTrackingLog -Server $_.Name -EventId AGENTINFO -MessageSubject "Rule test 01" `
-Start (Get-Date).AddHours(-1) -ResultSize Unlimited
}
$hits | Select-Object Timestamp, Source, @{n='AgentData';e={$_.EventData | Out-String}} | Format-List
$hits | Where-Object { ($_.EventData | Out-String) -match $rule.Guid } # entries that name your rule- Good: the transport rule agent's
AGENTINFOdata for the test message references your rule's GUID, and the action is visible in the delivered message. - Rule not referenced: it didn't match. Recheck conditions, exceptions and the header/envelope setting.
- Listed, but no visible change: the rule is still in a test mode, or a later rule changed the result.
- After any change: each Mailbox server logs Event ID 4002 in the Application log when its Transport service picks up a modified rule (Event ID 16028 on Edge Transport servers).
For reading tracking results in depth, see Message tracking on Exchange Server. To check the headers a rule added, see Reading email headers in Exchange Server.
Key takeaways#
- Check state, mode and dates before anything else; a rule in a test mode looks like it isn't working.
- Keep a documented rule order: rejections first, with stop processing, then tagging and disclaimers.
- Remember AND between conditions, OR between values, and that one exception beats everything.
- Use
HeaderOrEnvelopewhen relays and applications send on behalf of other addresses. - Rules run only where the message passes through transport: plan for Edge servers and Exchange Online separately. For cloud-side rule design, see Mail flow rules that don't backfire.

