How to verify an email address (without sending one)
How to verify an email address step by step: check syntax, look up MX records, ask the mail server over SMTP and test for catch-all, all without sending mail.
BounceOwl team7 min read
To verify an email address, check it in layers. First confirm the syntax, then confirm the domain has mail servers (MX records), then ask that mail server over SMTP whether the exact mailbox exists, and finally test whether the domain accepts every address (a catch-all). You can do the first two by hand in a minute. The last two are what an email verifier automates, and none of the four steps requires sending an email.
This guide walks through each method, what it catches, what it misses, and why the old trick of sending a test message causes more problems than it solves.
What each check tells you
No single test proves an address works. Each layer removes a different kind of bad address, and only the combination gives you an answer you can act on.
| Check | What it catches | What it misses |
|---|---|---|
| Syntax | Typos, missing @, spaces, stray punctuation from spreadsheets | Well-formed addresses that don't exist |
| Domain and MX | Dead domains, misspelled domains, domains that never receive mail | Mailboxes that were deleted on a live domain |
| SMTP mailbox check | Mailboxes the server rejects, disabled or full mailboxes | Domains that accept every address |
| Catch-all test | Domains where a yes from the server means nothing | Whether a specific person at that domain is real |
Step 1: check the syntax
Start with the shape of the address. A usable address has one @, a local part before it, and a domain with at least one dot after it. maya.chen@lumenforge.io passes. These do not:
maya.chen@lumenforgehas no top-level domain.maya chen@lumenforge.iohas a space in the local part.maya..chen@lumenforge.iohas two dots in a row.maya.chen@lumenforge.io,carries a trailing comma, a common leftover from copying cells out of a spreadsheet.
Keep your syntax rule loose. The standards allow plus signs, hyphens, apostrophes and long top-level domains, so a strict pattern copied from a forum will reject real people like o'neil+news@harborlane.com. Reject only what is clearly broken, and let the later steps do the rest.
While you are here, look for obvious domain typos: gmial.com, outlok.com, harborlane.con. A typo domain may pass the syntax check and even exist, but it is almost never what the person meant.
Step 2: check the domain and its MX records
A domain can only receive mail if it publishes mail exchanger (MX) records that tell senders where to deliver. You can look them up from any terminal:
# macOS or Linux
dig MX harborlane.com +short
# Windows
nslookup -type=mx harborlane.comIf the lookup returns one or more mail hosts, the domain is set up to receive mail. If it returns nothing, or the domain does not resolve at all, mail to any address there will fail. Strictly speaking, the mail standards let a sender fall back to the domain's main address record when no MX exists, but in practice a domain with no MX record is rarely a working mailbox.
The MX host also tells you who runs the mail, which matters later:
- Hosts ending in
google.comorgooglemail.compoint to Google Workspace. - Hosts ending in
mail.protection.outlook.compoint to Microsoft 365. - Hosts at
pphosted.comormimecast.compoint to a security gateway (Proofpoint or Mimecast) that sits in front of the real mail server.
Step 3: ask the mail server whether the mailbox exists
This is the step that separates a real verification from a guess. Mail servers talk to each other with SMTP, and the conversation has a point where the receiving server says whether it will take mail for a given recipient. A verifier uses that point and then hangs up:
- Connect to the domain's MX host on port 25.
- Introduce itself with a greeting (EHLO) and a sender address (MAIL FROM).
- Name the recipient (RCPT TO), for example maya.chen@lumenforge.io.
- Read the server's answer: the recipient is accepted, or rejected because the mailbox doesn't exist, is disabled or is full.
- Close the connection before any message content is sent.
No email is delivered and the recipient sees nothing. You can try this by hand with a tool like telnet or openssl, but expect trouble. Many home and cloud networks block outbound port 25. Servers slow down or refuse connections from addresses they don't recognize. Some servers use greylisting, which rejects the first attempt from a new sender and only accepts a retry minutes later. Getting a clean answer across thousands of domains takes retries, sensible pacing and a sending IP that mail servers will talk to.
Step 4: test for a catch-all domain
Some domains accept mail for every address, real or not. On those domains, step 3 always says yes, so the yes tells you nothing about the person you care about.
The test is simple: in the same session, ask the server about an address that cannot exist, such as qx7-no-such-person-41@harborlane.com. If the server accepts that too, the domain is a catch-all and your address needs a different approach. Our guide to catch-all email addresses covers what to do with them.
Why sending a test email is a bad idea
The oldest way to check an address is to email it and wait for a bounce. It feels direct, but it works against you:
- Bounces hurt your sender reputation. Mailbox providers watch how often your mail hits addresses that don't exist. Testing a list by sending to it produces exactly the bounces you were trying to avoid.
- Silence is not proof. A catch-all domain accepts the message and may drop it later without telling you. No bounce does not mean a person read it.
- Bounces arrive late. Some come back in seconds, some after the sending server has retried for a day or more.
- Real people see it. If the address works, a prospect now has a blank test message from you in their inbox.
- It doesn't scale. Tracking replies and bounces by hand stops working at a few dozen addresses.
When to use an email verifier
For one address you are curious about, steps 1 and 2 by hand are often enough to spot a dead domain. Use a verifier when the answer feeds into something that matters:
- Before a campaign, on every address you plan to send to.
- On signup forms, so a mistyped address doesn't become a lost customer.
- On imports into your CRM, so bad records don't spread to every tool downstream.
- When a list is more than a few weeks old, because people change jobs and mailboxes get shut down.
When you compare verifiers, ask a few practical questions:
- Does it check the mailbox live at the moment you ask, or return a stored answer of unknown age?
- Does it tell you which domains are catch-all instead of calling them valid?
- Does it show the evidence behind each answer, such as the mail server and provider it talked to?
- Does it charge you when the mail server gave no clear answer?
How to read the result
Most verifiers return a short set of verdicts. Here is how to act on each:
- Valid: the mailbox exists and accepts mail. Send.
- Invalid: the server rejected the mailbox, it is disabled or full, the domain has no mail server, or the syntax is broken. Remove it.
- Catch-all: the domain accepts everything, so the regular check can't tell. Keep it in a separate segment.
- Unknown: the server timed out, blocked the check or greylisted it. Try again later rather than sending.
Even a valid result is a snapshot of one moment. If you want to know why some addresses still bounce after a clean check, read why verified emails bounce.
Verify addresses with BounceOwl
BounceOwl runs these four steps for every address. It connects live to the recipient's mail server, asks about the mailbox, tests for catch-all, and shows you the evidence: the MX host, the mail provider or security gateway, the mailbox answer and when the check ran. No email is sent.
Check a single address in the email verifier, upload a CSV or XLSX file with bulk email verification, or call the email verification API from your own code. A live answer costs one credit, unknown results and invalid syntax are free, and new accounts get 100 free credits. The full rules are on the pricing page.
Check a list before you send it.
Live checks with evidence. Unknown results are free, and credits never expire.
Start with 100 free creditsKeep reading
6 min read
What is a catch-all email, and should you send to one?
What a catch-all email domain is, why accept-all servers make verification unreliable, how a made-up address test detects them and how to send to them safely.
BounceOwl team
7 min read
Why do verified emails bounce? Six causes and how to fix them
Why verified emails still bounce: stale results, catch-all domains, security gateways, full mailboxes and greylisting, plus practical steps to cut bounces.
BounceOwl team
8 min read
Email verification API: how to verify emails in your code
How to verify emails with an API: where to call it, curl, Python and Node examples for POST /v1/verify, handling 402 and unknown results, and bulk jobs.
BounceOwl team