Outbound queues piling up with 441 4.4.1 "Failed to connect" or 421 4.4.2 Connection dropped mean Exchange knows where the mail should go but can't hold an SMTP conversation with the destination. In this post I'll show how to tell a blocked port 25 from a dead smart host or a failing TLS handshake, fix the cause, and flush the queue before messages expire with 550 4.4.7.
Errors this guide fixes
441 4.4.1 Error encountered while communicating with primary target IP addressQueue Viewer / Get-Queue LastError+4 more guidesFailed to connect. Winsock error code: 10060, Win32 error code: 10060.Get-Queue LastError+2 more guidesAttempted failover to alternate host, but that did not succeed.Get-Queue LastError421 4.4.2 Connection dropped due to SocketErrorGet-Queue LastError+1 more guide550 4.4.7 QUEUE.Expired; message expiredNDR+1 more guide451 4.4.0 Error encountered while communicating with primary target IP addressGet-Queue LastErrorEither there are no alternate hosts, or delivery failed to all alternate hosts.Get-Queue LastError
Symptoms#
Mail to some or all external domains, or to your smart host, isn't leaving. Get-Queue shows the queue in Retry with a LastError like one of these:
441 4.4.1 Error encountered while communicating with primary target IP address: "Failed to connect.
Winsock error code: 10060, Win32 error code: 10060." Attempted failover to alternate host, but that
did not succeed. Either there are no alternate hosts, or delivery failed to all alternate hosts.
The last endpoint attempted was 203.0.113.25:25
451 4.4.0 Error encountered while communicating with primary target IP address: "421 4.4.2 Connection
dropped due to SocketError." Attempted failover to alternate host, but that did not succeed. ...Senders first get a delay notification (after four hours by default). When the message expiration timeout runs out (two days by default), they get an NDR with:
550 4.4.7 QUEUE.Expired; message expiredWhy it happens#
Exchange has already resolved the destination; if DNS were the problem you'd see 451 4.4.0 DNS query failed instead. It tries each address of each MX host or smart host in turn (that's the "failover to alternate host"), and when none works, the queue goes to Retry. The two codes fail at different stages:
| Error | What happened | Look first at |
|---|---|---|
Winsock error code: 10060 | The TCP connection timed out: nothing answered on port 25 | Outbound firewall or NAT, ISP or cloud egress blocks, remote host down |
421 4.4.2 Connection dropped due to SocketError | The connection opened but the session broke part-way | TLS negotiation, firewall SMTP inspection, remote throttling, large-message (MTU) problems |
550 4.4.7 QUEUE.Expired | Exchange gave up after the expiration timeout | Whatever error the queue showed before |
If only one domain is affected, the fault is usually on the recipient's side. If every domain fails, look at your egress path, your smart host or your TLS configuration.
How to fix it#
1. Scope it#
Get-Queue -Server EX01 | Where-Object { $_.Status -eq "Retry" } |
Format-List Identity, DeliveryType, NextHopDomain, MessageCount, LastError, NextRetryTimeDnsConnectorDelivery means MX-based delivery; SmartHostConnectorDelivery means a smart host. Note the address after "The last endpoint attempted was".
2. Check the connector and the source servers#
Get-SendConnector | Format-List Name, AddressSpaces, DNSRoutingEnabled, SmartHosts, Port,
SourceTransportServers, FrontendProxyEnabled, RequireTLS, TlsAuthLevelEvery server in SourceTransportServers needs outbound TCP 25 (or the connector's Port). If FrontendProxyEnabled is True, connections leave through the Front End Transport service, so the firewall rule must cover those servers as well.
3. Test the TCP path from each source server#
Test-NetConnection -ComputerName 203.0.113.25 -Port 25
Test-NetConnection -ComputerName smarthost.contoso.net -Port 25You want TcpTestSucceeded : True. If it's False from your server but the same test works from a machine outside your network, something on your side drops the traffic: a firewall rule, a NAT change, or a provider that restricts outbound port 25 (Azure, for example, does this for many subscription types). If it fails from everywhere, the remote host is down; send the recipient's admins the IP address from the error.
4. Read the send protocol log#
Set-SendConnector "Internet" -ProtocolLoggingLevel Verbose
$log = Join-Path $env:ExchangeInstallPath "TransportRoles\Logs\Hub\ProtocolLog\SmtpSend"
Select-String -Path "$log\*.LOG" -Pattern "203.0.113.25" | Select-Object -Last 40With FrontendProxyEnabled, look under TransportRoles\Logs\FrontEnd\ProtocolLog\SmtpSend instead. In each line, + is a connect, > is what Exchange sent, < is the remote answer and - is a disconnect. A healthy session shows the remote 220 banner, your EHLO, a 250 reply offering STARTTLS, the TLS handshake, then MAIL FROM, RCPT TO and DATA. A session that ends right after STARTTLS points at TLS; one that dies during DATA, only for large messages, points at the network path.
5. Fix the cause#
- Port 25 blocked: allow outbound TCP 25 from every source server (and the Front End servers if proxying). If your provider won't open it, send through an authenticated smart host on its submission port instead.
- Smart host unreachable: confirm it's up and accepts your server's IP address, and list a second smart host so failover has somewhere to go.
- TLS failures: run the Exchange Server Health Checker, which flags inconsistent TLS settings, and disable firewall SMTP/ESMTP inspection features that rewrite or strip STARTTLS. For the hybrid connector, check the certificate as described in renewing the hybrid certificate.
- Drops only on large messages: send a small test and one with a large attachment. If only the large one fails, check MTU, fragmentation and idle timeouts on firewalls or VPN tunnels on the path.
Example of moving the internet connector to an authenticated smart host on port 587:
Set-SendConnector "Internet" -DNSRoutingEnabled $false -SmartHosts relay.example.net -Port 587 `
-SmartHostAuthMechanism BasicAuthRequireTLS -AuthenticationCredential (Get-Credential)6. Retry and watch the messages#
Retry-Queue -Identity "EX01\fabrikam.com"
Get-Message -Queue "EX01\fabrikam.com" |
Format-Table FromAddress, Subject, RetryCount, LastError, ExpirationTime -AutoSizeExpirationTime tells you how long you have before each message becomes a 4.4.7 NDR. After changing a connector's routing, run Retry-Queue with -Resubmit $true so the messages are routed again over the new path.
Note: Exchange retries on its own schedule, so a fixed firewall rule doesn't empty the queue instantly. Retry-Queue forces an immediate connection attempt.
Verify the fix#
Get-Queueshows the queue draining:MessageCountfalling andLastErrorempty.- The protocol log shows complete sessions that end with QUIT.
- Message tracking shows
SENDevents with the remote server's 250 response inRecipientStatus:
Get-MessageTrackingLog -Server EX01 -EventId SEND -Start (Get-Date).AddHours(-1) |
Where-Object { $_.Recipients -like "*@fabrikam.com" } |
Format-Table Timestamp, Recipients, RecipientStatus -AutoSizePrevent it next time#
- Document the required egress (TCP 25 from each source server, plus Front End servers when proxying) and re-test it after every firewall or NAT change.
- Alert on queues in Retry or above a message count, for example
Get-Queue | Where-Object { $_.MessageCount -gt 50 }, long before the two-day expiration. - Give connectors redundancy: two smart hosts and more than one source server.
- Re-run Health Checker after every CU or security update to catch TLS drift.
- If the backlog comes from the server itself being under resource pressure, see 452 4.3.1 back pressure explained.

