SMTP Validation Explained: How Email Validators Really Work

SMTP Validation Explained: How Email Validators Really Work

Most email checkers claim accuracy. Few explain how they actually verify an address.

This is that explanation.

What is SMTP?

SMTP = Simple Mail Transfer Protocol
It's the language mail servers use to send and receive email.

When you send an email:
1. Your client connects to an SMTP server
2. Sends MAIL FROM: you@yourcompany.com
3. Sends RCPT TO: recipient@their.com
4. Server responds 250 OK (yes, we accept it) or 550 Reject (no, we don't)
5. Client sends the message body

SMTP Validation: The Real Check

SMTP validation simulates steps 1–4 without sending the actual email.

This is why it's the only way to know if a mailbox truly exists.

The SMTP Handshake

→ Client: EHLO mail.validator.com
← Server: 250 OK ESMTP

→ Client: MAIL FROM:<validator@mail.validator.com>
← Server: 250 OK

→ Client: RCPT TO:<test@gmail.com>
← Server: 250 OK
     (mailbox exists and accepts mail)

→ Client: QUIT
← Server: 221 Bye

If the RCPT TO returns 250, the address is Valid.
If it returns 550, the address is Invalid.
If the server doesn't respond, it's Risky or Unknown.

Why Other Methods Fail

❌ Syntax Check Only

test@example.com ✅ (looks good)
test.12345@example.com ❌ (might not exist)

Syntax is correct but we don't know if the mailbox exists.

❌ MX Record Check Only

Domain: gmail.com → MX: aspmx.l.google.com (yes, exists)
But: does test@gmail.com actually exist? Unknown.

✅ SMTP Validation

Connect to gmail SMTP → RCPT TO test@gmail.com
← 550 No such user
Result: INVALID (mailbox doesn't exist)

The Challenge: Catch-All Domains

Some servers (especially older ones) say "yes" to every address:

→ RCPT TO: realuser@company.com
← 250 OK

→ RCPT TO: fakeuser123456789@company.com
← 250 OK (also accepted!)

These are catch-all domains. The SMTP check alone can't tell if it's real.

Advanced: Scoring + Catch-All Detection

Better validators combine SMTP + other signals:

  • Domain reputation — is the mail server known to bounce?
  • Recent activity — was this domain active in the last 90 days?
  • Honeypot checks — is it a known spam trap?
  • Risky + catch-all flag — "Valid by SMTP but could be catch-all"

Score 0–10 = confidence level, not just pass/fail.

Speed vs Accuracy

Method Speed Accuracy Cost
Syntax <1ms 60% Free
MX check 50ms 75% Free
SMTP 500ms–2s 95% ¢
SMTP + scoring 1–5s 99% ¢¢

Why SMTP Validation Matters

✅ Protects sender reputation — verify before sending
✅ Reduces bounce rates — SMTP catches invalid before send
✅ Saves on credits — don't pay ESP for bounced emails
✅ Improves deliverability — ISPs reward clean sending

How to Verify Yourself (Dev Only)

import smtplib

domain = "gmail.com"
try:
    smtp = smtplib.SMTP(f"mx.{domain}")
    smtp.mail("test@validator.com")
    code, msg = smtp.rcpt("recipient@gmail.com")
    if code == 250:
        print("Valid")
    else:
        print("Invalid")
    smtp.quit()
except:
    print("Risky/Unknown")

But in production, use a service. SMTP validation at scale is complex (firewalls, rate limits, delays).

SMTP in More Detail

SMTP is a text protocol. A session is a short conversation with a sequence of commands and numeric replies. For validation, only the first half matters — the part before any message body is sent.

Ports and TLS

  • 25 — the classic server-to-server port. Often blocked by hosting providers to stop spam, which is why validation services use dedicated infrastructure.
  • 465 — implicit TLS (SMTPS).
  • 587 — submission port with STARTTLS, used by mail clients.

A validator needs port 25 reachability to the recipient's MX. If your own server cannot reach port 25, you cannot run reliable SMTP checks yourself — this is the most common reason teams outsource verification.

EHLO, MAIL FROM, RCPT TO

→ EHLO validator.example.com
← 250-mail.example.com
← 250-PIPELINING
← 250 SIZE 35882577

→ MAIL FROM:<check@validator.example.com>
← 250 OK

→ RCPT TO:<person@example.com>
← 250 OK

EHLO opens the session and asks which extensions the server supports. MAIL FROM declares the envelope sender. RCPT TO is the actual test: the server accepts or rejects the recipient. QUIT ends the session.

The key point: RCPT TO is answered before any message data is sent. That is what makes validation possible without delivering mail.

Reading SMTP Response Codes

Code Meaning Validation interpretation
250 Requested action completed Valid (unless catch-all)
251 User not local, will forward Valid
450 Mailbox unavailable, try later Risky
451 Local error, try later Risky
452 Insufficient storage Risky (full mailbox)
550 Mailbox unavailable Invalid
551 User not local Invalid
552 Storage exceeded Risky
553 Mailbox name not allowed Invalid
421 Service not available Unknown, retry

A validator that treats every non-250 reply as "invalid" is wrong: 4xx codes are temporary and often resolve on retry.

Why Syntax and MX Checks Are Not Enough

Both are cheap and useful as a first filter, but neither can answer the only question that matters: does this mailbox accept mail?

  • Syntax tells you the string looks like an address. It cannot see that the company closed.
  • MX tells you the domain has a mail server. It cannot see that person@ was never created.
  • SMTP talks to that server and asks about that specific recipient. Only this step returns a real answer.

The practical consequence: a list that passes syntax and MX checks can still bounce at 20–30%. That is why "free email checker" tools that only run regex are popular and useless for deliverability work.

Catch-All Domains in Depth

A catch-all server is configured to accept mail for any local part. That is a legitimate configuration — companies use it so a typo in a prospect's address does not silently disappear — but it breaks SMTP validation.

How to handle catch-alls:

  1. Detect them. Send a probe to a random, obviously fake local part. If it also returns 250, the domain is catch-all.
  2. Flag, don't delete. Catch-alls are often real people. Deleting them can cost 5–15% of a B2B list.
  3. Send in small batches and measure opens and bounces. If a catch-all segment performs, keep it.
  4. Use additional signals — domain reputation, historical engagement, and pattern matching — to rank catch-all addresses.

Greylisting, Rate Limits and Anti-Harvesting

Real mail servers are not test harnesses. Expect:

  • Greylisting — the server temporarily rejects first-time senders with a 4xx and expects a retry. Validation services retry automatically.
  • Rate limiting — too many connections from one IP get throttled. Good providers spread checks across IPs and time.
  • Anti-harvesting — some servers deliberately answer ambiguously to anyone probing many addresses.
  • Honeypots — addresses that exist only to catch bulk senders. A good validator flags them.

This is why DIY validation scripts work on ten addresses and fall apart on ten thousand.

Real-Time vs Batch, and the Async Pattern

  • Real-time is right for signup forms and checkout: one address, one immediate answer, with a strict timeout so the user never waits more than a second or two.
  • Batch is right for lists: thousands of addresses, retries, and a result file you can segment.
  • Async is the production pattern for both: queue the address, return immediately, verify in the background, and update the record when the result arrives.

Never block a request thread on a remote SMTP handshake. A slow or hostile server can hold the connection for 30 seconds or more.

A Better Python Example

import smtplib
import dns.resolver

def check(domain: str, address: str, timeout: int = 10) -> str:
    try:
        mx = str(dns.resolver.resolve(domain, "MX")[0].exchange).rstrip(".")
        with smtplib.SMTP(mx, 25, timeout=timeout) as smtp:
            smtp.ehlo_or_helo_if_needed()
            smtp.mail("check@validator.example.com")
            code, _ = smtp.rcpt(address)
            if code in (250, 251):
                return "valid"
            if code in (450, 451, 452, 552):
                return "risky"
            if code in (550, 551, 553):
                return "invalid"
            return "unknown"
    except Exception:
        return "unknown"

Even this simplified version has problems at scale: it ignores greylisting, does not detect catch-alls, uses one IP, and will be blocked by providers that rate-limit. It is a learning tool, not a production validator.

Limitations and Ethics

No validator can guarantee deliverability. Mailboxes close between the check and the send; servers change policy; a "valid" address can still be abandoned. Use verification to remove predictable failures, not to promise a zero-bounce campaign.

Ethically, validate addresses you have a lawful basis to contact. SMTP probing is a technical operation, but it does not create consent, and using validation to launder a purchased list does not make the sending legal.

What Validation Cannot See

  • Engagement — a valid address may never open your email.
  • Intent — a real person may not want your offer.
  • Consent — a deliverable address is not a lawful basis.
  • Future state — a mailbox can be closed the day after you verify it.

Verification removes technical uncertainty. Everything else is still marketing.

Testing Your Own Domain First

Before validating a list, validate your sending domain:

  • Send a test to a mailbox you control at Gmail, Outlook and a corporate domain.
  • Check SPF, DKIM and DMARC alignment.
  • Watch the first 200 sends of any new domain closely; warm-up matters more than any single verification run.

A clean list sent from a domain with broken authentication still lands in spam.

Frequently Asked Questions

Does SMTP validation send an email?
No. It stops at RCPT TO, before any message body is transmitted.

Why do some valid addresses come back as risky?
Greylisting, temporary server errors, or anti-harvesting policies. Retry after 24–48 hours.

Can I validate from my own server?
Only if it can reach port 25 and is not rate-limited or blacklisted. Most shared hosts block it.

Is catch-all detection reliable?
It reliably tells you the domain is catch-all. It cannot tell you whether a specific mailbox exists.

What accuracy should I expect?
A good SMTP-based validator is right about 95–99% of the time; the remaining uncertainty is dominated by catch-alls and temporary failures.

SPF, DKIM and DMARC in One Paragraph Each

  • SPF lists the servers allowed to send for your domain. It is a DNS TXT record, and it breaks when you exceed the 10-lookup limit.
  • DKIM adds a cryptographic signature to each message so the receiver can prove it was not altered. Rotate keys periodically.
  • DMARC tells receivers what to do when SPF or DKIM fails (none, quarantine, reject) and sends you reports. Start with p=none, read the reports, then tighten.

SMTP validation checks the recipient; SPF, DKIM and DMARC determine whether your own mail is trusted on the way out. A verified list sent from a domain with broken authentication still fails. Set up DMARC reporting before you scale a campaign — the reports are how you find the senders you forgot about.

Start Validating

Get started free →

100 SMTP validations/month, no credit card.

Ready to clean your email list?

200 free verifications. No credit card. Full SMTP validation in under 1 second.

🚀 Create Free Account
MP

Milan Pasić

Milan Pasić is the founder of N-Software and lead developer of Email Validator. He has spent over a decade building email infrastructure, deliverability tools, and SMTP validation systems used by thousands of marketers and developers worldwide.