How to tell whether a mail domain is really live, without sending anything
Test emails are a poor instrument. You get one sample, you cannot repeat it cheaply, and every failure leaves a bounce in somebody inbox.
When mail is not arriving, the instinct is to send a test. That gives you one sample from one server at one moment, and if it fails you have created a bounce. There is a better way to ask the same question.
Ask the mail server directly
An SMTP conversation can get as far as naming a recipient and then hang up. Nothing is sent, nothing is delivered, and no bounce is generated. The server tells you whether it would accept that address.
$tcp = New-Object System.Net.Sockets.TcpClient("yourdomain-com.mail.protection.outlook.com", 25)
$stream = $tcp.GetStream()
$reader = New-Object System.IO.StreamReader($stream)
$writer = New-Object System.IO.StreamWriter($stream)
$writer.AutoFlush = $true
$reader.ReadLine()
$writer.WriteLine("EHLO example.org"); Start-Sleep -Milliseconds 800
while ($stream.DataAvailable) { $reader.ReadLine() }
$writer.WriteLine("MAIL FROM:<test@example.org>"); Start-Sleep -Milliseconds 800
while ($stream.DataAvailable) { $reader.ReadLine() }
$writer.WriteLine("RCPT TO:<someone@yourdomain.com>"); Start-Sleep -Milliseconds 800
while ($stream.DataAvailable) { $reader.ReadLine() }
$writer.WriteLine("QUIT"); $tcp.Close()
Probe an address that does not exist
This is the part that makes it diagnostic rather than merely reassuring. Probing a real mailbox tells you it works. Probing a deliberately fake address tells you what kind of no you are getting:
- A 550 recipient rejection means the server knows the domain and is correctly refusing an unknown mailbox. Healthy.
- A 551 unable-to-relay response means the server does not believe the domain belongs to that organisation at all. Broken.
Without the fake-address control you cannot distinguish the two, because a real address returning 250 on one server tells you nothing about the others.
Loop it and log the server name
Large mail platforms sit behind many front-end servers and you hit a different one each time. Recording which server answered turns a yes or no into a picture.
During a domain migration this showed us the fleet converting one server at a time over several hours, with individual servers flipping from refusing the domain to accepting it and then staying converted. Roughly a third had done so after an hour. That was invisible from any portal.
Probe every 20 to 30 seconds, not every 2. We ran it too aggressively and had the source IP rate limited, at which point connections simply stopped and the instrument became useless.
Where else this applies
The general point is not about mail. When a system is behind a load balanced fleet, a single test tells you about one member. If the fleet can be inconsistent, and during any configuration change it can, you need a cheap repeatable probe that records which member answered. Otherwise you are debugging an average.
Outbound port 25 is blocked on many residential connections, which will make the connection itself fail. That is your ISP rather than the domain.
Need help with any of this?
These notes are free and always will be. If you would rather someone just set it up, or you are stuck on something similar, get in touch at hello@opsira.io.