Your scanner, ERP system or monitoring tool can email internal users, but every message to an outside address fails with 550 5.7.54 SMTP; Unable to relay recipient in non-accepted domain. That is Exchange correctly refusing to act as an open relay. In this post I'll show how to allow relay for exactly those hosts with a dedicated receive connector, test it, and make sure you haven't opened the server to the internet. The steps apply to Exchange Server SE, 2019 and 2016.
Errors this guide fixes
550 5.7.54 SMTP; Unable to relay recipient in non-accepted domainSMTP session / application log+7 more guides550 5.7.1 Unable to relayTelnet / SMTP session
Symptoms#
The application's SMTP log, or a manual Telnet test, shows the rejection at the RCPT TO stage:
MAIL FROM:<scanner@contoso.com>
250 2.1.0 Sender OK
RCPT TO:<supplier@fabrikam.com>
550 5.7.54 SMTP; Unable to relay recipient in non-accepted domain- Recipients in your own accepted domains work; only external addresses fail.
- Older Exchange versions, and Microsoft's own Telnet test steps, use the wording
550 5.7.1 Unable to relayfor the same condition. - It typically starts after applications move to a new Exchange server, after an application server's IP address changes, or when a load balancer or NAT device is placed in front of Exchange.
Why it happens#
An unauthenticated connection to port 25 on a Mailbox server lands on the Default Frontend <ServerName> receive connector in the Front End Transport service. That connector has to accept anonymous mail, because that's how internet mail reaches you, but only for recipients in your accepted domains. Sending to any other domain needs the ms-Exch-SMTP-Accept-Any-Recipient permission, which anonymous senders don't have there, so Exchange answers 5.7.54.
When several connectors listen on the same address and port, Exchange uses the one whose remote IP ranges match the connecting IP most specifically. So the fix is a dedicated connector that lists only your application servers. If their IP isn't on that list, or Exchange sees a load balancer's or firewall's address instead, Default Frontend answers and the relay fails.
How to fix it#
1. Find out which IP Exchange sees and which connector answered#
Get-ReceiveConnector -Server EX01 | Format-Table Name, TransportRole, Bindings, RemoteIPRanges -AutoSize
$log = Join-Path $env:ExchangeInstallPath "TransportRoles\Logs\FrontEnd\ProtocolLog\SmtpReceive"
Select-String -Path "$log\*.LOG" -Pattern "5.7.54" | Select-Object -Last 5Each protocol log line includes the connector name and the remote endpoint (IP address and port). If the remote IP is a load balancer, NAT or gateway address rather than the application server, that's the address Exchange matches on. If nothing is logged, turn on logging with Set-ReceiveConnector "EX01\Default Frontend EX01" -ProtocolLoggingLevel Verbose.
2. Create a dedicated Frontend connector#
New-ReceiveConnector -Name "Anonymous Relay" -Server EX01 -TransportRole FrontendTransport -Custom `
-Bindings 0.0.0.0:25 -RemoteIPRanges 10.10.20.15,10.10.20.16Create it in the Front End Transport service, not the Transport service, whose default connector listens on port 2525 for other Exchange servers. RemoteIPRanges accepts single addresses, ranges and CIDR notation; be as specific as you can. Repeat on every Mailbox server your applications use. In the Exchange admin center, the same task is Mail flow › Receive connectors › Add, with role Frontend Transport and type Custom.
3. Grant relay with one method, not both#
Method A, anonymous relay (least privilege, and the one I'd default to):
Set-ReceiveConnector "EX01\Anonymous Relay" -PermissionGroups AnonymousUsers
Get-ReceiveConnector "EX01\Anonymous Relay" |
Add-ADPermission -User "NT AUTHORITY\ANONYMOUS LOGON" -ExtendedRights "Ms-Exch-SMTP-Accept-Any-Recipient"Method B, externally secured:
Set-ReceiveConnector "EX01\Anonymous Relay" -AuthMechanism ExternalAuthoritative -PermissionGroups ExchangeServers| Method | Hosts are treated as | Antispam and size limits | Use it when |
|---|---|---|---|
| A: AnonymousUsers + Accept-Any-Recipient | Anonymous senders | Still applied | Most applications and devices |
| B: ExternalAuthoritative + ExchangeServers | Authenticated internal senders | Bypassed | Hosts you trust completely |
4. Point the application at the server#
Configure the application to use the Exchange server's FQDN or IP address on port 25 without authentication. If the application can sign in with a mailbox, authenticated submission on port 587 (the Client Frontend connector) is the better design and needs no relay connector at all.
Watch out: If a load balancer or firewall source-NATs connections, Exchange sees its address, not the application's. Never add that address to the relay connector if internet traffic can also arrive from it, because you'd have built an open relay. Preserve the client IP on the load balancer, or point applications at the servers directly.
Verify the fix#
Get-ReceiveConnector "EX01\Anonymous Relay" | Format-List Enabled, TransportRole, Bindings, RemoteIPRanges, PermissionGroups
Get-ReceiveConnector "EX01\Anonymous Relay" | Get-ADPermission -User "NT AUTHORITY\ANONYMOUS LOGON" |
Where-Object { -not $_.Deny -and -not $_.IsInherited } | Format-Table User, ExtendedRightsThen test from an allowed host with the Telnet Client or any SMTP test tool. After RCPT TO with an external address you should get 250 2.1.5 Recipient OK, and after the message body 250 2.6.0 ... Queued mail for delivery. Run the same test from a host that isn't on the list, and from outside your network if port 25 is published, and confirm you still get 550 5.7.54. Finally, check that the message left the organization:
Get-TransportService | Get-MessageTrackingLog -Sender scanner@contoso.com -Start (Get-Date).AddMinutes(-30) |
Format-Table Timestamp, EventId, Source, Recipients -AutoSizeGood looks like a RECEIVE event followed by a SEND through your internet send connector or smart host.
Prevent it next time#
- Never add relay rights to the default receive connectors, and never use
0.0.0.0-255.255.255.255on a relay connector. Microsoft explicitly advises against adding anonymous relay to the default connectors. - Audit who can relay. Only your dedicated relay connectors should appear in this output:
Get-ReceiveConnector | Get-ADPermission -User "NT AUTHORITY\ANONYMOUS LOGON" |
Where-Object { $_.ExtendedRights -like "*Accept-Any-Recipient*" } | Format-Table Identity, User -AutoSize- Keep a record of each allowed IP address and its owner, and remove decommissioned hosts.
- When you build new servers, for example moving to Exchange Server SE on new hardware, recreate the relay connector on them before you repoint the applications.
- If relay works only intermittently, review the message rate and throttling settings on the connector.
- Relaying through Exchange Online instead? See SMTP AUTH, relay connectors and 5.7.57.

