Skip to content

Build1 publisher2 min readPublished

Port 25 decides which email check you can actually run

An MX lookup is one DNS query proving a domain has mail servers. Confirming a specific mailbox means opening port 25 from an IP that Gmail will answer, so MailProbe ships that check only in its self-hosted build.

The Engineer · Build desk

Illustration accompanying Port 25 decides which email check you can actually run

What happened

  • MX records show only that a domain has mail servers willing to accept mail, and say nothing about whether the local part before the @ belongs to a real inbox.
  • SMTP verification goes one step further by connecting to the MX host on port 25, naming the recipient and reading the reply code, where 250 means the mailbox exists and 550 means it does not.
  • Port 25 is blocked on most cloud hosts and residential networks, the same places application code usually runs.
  • When the MX lookup fails for network reasons, the verifier returns deliverable: null with reason mx_timeout rather than false.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint Inbox-level checking is reachable only by teams that already run warmed sending infrastructure, because the write-up puts IP warming at weeks of real volume and real engagement, and renting the reputation carries its own cost.
  • decision Signup code now needs a third path for addresses it could not prove, because a two-branch accept/reject flow silently assigns null to one side or the other.
  • exposure On catch-all domains the stronger check clears addresses nobody reads, so paying for SMTP verification does not close the hole it was bought to close.
  • cost Mapping unknown to invalid charges a transient DNS failure to the signup funnel, and the customer who bounces off it never appears in an error log.

The field carrying the design is `deliverable`, and it does not behave like a boolean. On a domain with no MX records, the verifier returns `valid: false` but `deliverable: null`, with `reason: "no_mx"`, `score: 0`, `syntax: true` and an empty record list [4]. The write-up says the null is deliberate: the domain does not resolve, so the verifier cannot claim the address is undeliverable in every sense, and the safer claim is that it is unproven [5]. The passing case is different. `[email protected]` comes back `valid: true`, `deliverable: true`, `reason: "ok"`, `score: 90`, with two MX hosts at priority 5 and 10 and `provider: "google-workspace"` [6].

So `valid` and `deliverable` answer different questions, and `deliverable` has three possible answers where most signup code has two branches [19]. According to the write-up, calling code should read null as "ask again later" or "let the user through with a confirmation email", never as a hard reject [16]. A network timeout during an MX lookup tells you that the DNS query did not come back [17].

The hosted-versus-self-hosted split is a runtime constraint. Cloudflare Workers has no raw TCP, so the hosted endpoint cannot open a socket to port 25 at all, while the self-hosted Node build can because it controls the runtime [12]. The write-up attributes the demotion of SMTP checking from a default feature to a specialist, self-hosted one to sending reputation [18]. Gmail and Microsoft read the probing IP's history before they answer, and a cold IP with no track record is throttled or refused outright [13]. Major providers reject connections that do not come from a reputable, warmed-up sending IP [9].

Even a probe that connects can be answered dishonestly. Some servers report success for every address specifically to avoid confirming which accounts exist, which is the information attackers are after [11].

The evidence here is two example API responses for two addresses [22]. The write-up does not give the frequency of catch-all domains, the production rate of `mx_timeout`, or the number of good signups the null saved. For the three-state design to earn anything in your flow, you need somewhere to put an unproven address: a retry, or an account created behind a confirmation click [16]. If your code has only accept and reject, null is a value you will map onto one of them.

What to watch

  • Whether MailProbe publishes production rates for mx_timeout and null outcomes, which would let callers size the retry path.
  • Whether raw TCP outbound arrives in Cloudflare Workers, since that is the single blocker on hosted SMTP probing.
  • Whether Gmail and Microsoft tighten how they answer probes from IPs with no sending history.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories