Cloudflare-fronted disposable detection
When a disposable-mail provider sits behind Cloudflare, the classical MX-fingerprint detection approach breaks. The MX record points at Cloudflare’s Email Routing infrastructure, not at the operator’s own back-end, so the MX hostname is route1.mx.cloudflare.net — a real Cloudflare-hosted MX that legitimate domains also use. You can’t blocklist Cloudflare. You can’t safely return disposable based on a Cloudflare MX hostname alone, because half the privacy-conscious indie-blog operators on the internet also use Cloudflare Email Routing for their personal forwarding.
This is the problem behind the weighted-disposable verdict. In our production database, 5,258 domains carry this verdict: domains we have strong reason to believe are disposable based on signals other than MX, but where we won’t return a hard result: undeliverable because the MX layer can’t confirm it. Real domains in this bucket include temp-mail.org, mail.tm, 33mail.com, simplelogin.io, and a few thousand smaller operators using Cloudflare’s infrastructure to host their disposable services without exposing their own MX servers.
This post: why Cloudflare is a detection problem, what signals we use instead, and how the weighted-disposable verdict differs from the standard disposable one.
Why MX-fingerprinting breaks at Cloudflare
The Tier-2 detection on our disposable email checker API does two things:
- Exact MX hostname match — if
dig MX example.comreturnsgourmet.spamgourmet.com, that hostname matches a known operator MX backend and the domain is flagged. - Parent-domain MX pattern match — if the MX is
mx99.add5000.com, the parentadd5000.commatches a regex pattern and the domain is flagged.
Both rely on the MX record exposing operator-specific infrastructure. Cloudflare’s Email Routing inverts that. The MX records look like:
$ dig +short MX temp-mail.org
1 route1.mx.cloudflare.net.
2 route2.mx.cloudflare.net.
3 route3.mx.cloudflare.net.
route1.mx.cloudflare.net is Cloudflare’s MX server. It hosts mail routing for millions of legitimate domains — small businesses, personal blogs, privacy enthusiasts forwarding to their main inbox. Treating “MX points at Cloudflare” as evidence of disposable would over-block by several orders of magnitude.
The fix isn’t a better MX rule. It’s a different signal layer.
Signals that survive Cloudflare
Five signals stack to produce the weighted-disposable verdict:
- Domain in known disposable blocklists. Even if MX detection fails, a brand new domain a public blocklist already lists is a strong signal.
temp-mail.orgis on every disposable list ever published. - HTML scrape revealing temp-mail UI. The Playwright probe visits the apex domain, looks for keywords like “temporary email,” “disposable inbox,” “no signup,” and identifying UI patterns (the address-dropdown widget, inbox-by-URL pattern). If it scrapes as a temp-mail site, that’s a strong signal independent of MX.
- Fingerprint cluster match. If the apex shares AdSense, GA4, or GTM IDs with a known disposable operator, it joins that cluster. Detailed in our fingerprint-clustering post.
- Operator-self-reference. If the apex’s HTML lists multiple “available” mail domains in a dropdown, those domains are recorded as mail domains for that operator. The apex itself often qualifies.
- Customer-consensus. When ≥3 distinct vrfymail customers report bounces on a domain within 30 days, the domain promotes to a global flag. This works on Cloudflare-fronted domains the same as anywhere else — the MX layer doesn’t matter for bounce-feedback signals.
A domain scoring on 3+ of those 5 signals goes into the weighted-disposable bucket. The naming reflects the underlying uncertainty: we’re confident it’s disposable based on multi-signal evidence, but we can’t reach the same MX-corroborated confidence as a Tier-1 or Tier-2 hit, so we tag the verdict to reflect that.
What the verdict looks like at the API
A typical /v1/check response on a weighted-disposable domain:
{
"result": "undeliverable",
"reason": "disposable",
"reason_message": "This email provider doesn't deliver mail reliably. Please use a real address.",
"disposable": true,
"score": 0.15,
"trap": { "listed": false, "lists": [], "code": null }
}
A few notes. The top-level result is still undeliverable — your form’s primary handling path doesn’t change. The score field carries the underlying confidence: a Tier-1 hit returns score: 0.0 (highest confidence it’s bad), a weighted-disposable returns score: 0.15 (high confidence with a small uncertainty margin). If your handler wants finer control — accept anything with score > 0.5, flag 0.15-0.5, block ≤ 0.15 — the score is the lever.
The Cloudflare-fronted operators we’ve identified
A sample of weighted-disposable domains from the production table:
- temp-mail.org / temp-mail.io / temp-mail.ru — the same brand under three TLDs, all behind Cloudflare. The mostly-known free temp-mail product.
- mail.tm — popular API-driven temp-mail with developer docs. Cloudflare-fronted.
- emailondeck.com — mature provider with a paid tier, Cloudflare-fronted MX.
- mytemp.email — generic temp-mail UI, fingerprint-cluster matches a budget hosting backend.
- smailpro.com — temp-mail with a forwarding option. Cloudflare-fronted.
- 33mail.com — alias-forwarder service (Cloudflare for the apex, separate MX for forwarding).
- simplelogin.io / simplelogin.com — the legitimate-privacy alias-forwarder, also fronted by Cloudflare. Returns
risky / alias_forwardernotundeliverable / disposable.
The full list extends to over 5,000 domains, dominated by the long tail of one-or-two-domain operators using Cloudflare’s free Email Routing tier as their MX layer. The big-name brands (temp-mail family, mail.tm, mailinator’s secondary domains) are the visible top.
Why Cloudflare doesn’t help us with their own infrastructure
This question comes up a lot. Cloudflare offers Email Routing as a free feature; abuse of it for disposable-mail providers is something they could in principle filter, but in practice doesn’t get tackled at scale. Our experience: Cloudflare-fronted disposable operators stay up indefinitely unless they trip a separate abuse signal (DMCA, phishing, fraud reports targeting another tenant). For our detection, the practical assumption is that any Cloudflare MX could be hosting a temp-mail product, and we need orthogonal signals to confirm.
What this changes for your signup form
The handling is the same as for a Tier-1 hit. The only difference is internal: how confident we are in the verdict. Your code doesn’t need to branch on score unless you want to:
if (verdict.result === "undeliverable") {
// Includes both Tier-1 disposable hits and weighted-disposable hits.
// reason_message is end-user copy already mapped per reason.
return { error: verdict.reason_message };
}
If you want finer control — e.g., you’re running a free educational product where you’d rather accept a borderline case than reject a legitimate user — branch on score:
if (verdict.score < 0.05) {
// High confidence undeliverable — block.
return { error: verdict.reason_message };
}
if (verdict.score < 0.3) {
// Weighted-disposable. Block in B2B, allow in B2C with soft warning.
return { warning: verdict.reason_message };
}
// Accept.
Most signup flows ship the simpler version. The score is there for the cases that need it.
How the bucket grows
The weighted-disposable table grows from three sources, in order of contribution:
- Daily public-blocklist sync — ~70% of new entries. The npm
disposable-email-domainspackage and similar lists feed candidate domains; the ones that pass the legit-allowlist filter and pass the temp-mail-UI HTML probe land in the bucket. - CT-log scanning of new TLS issuances — ~20%. New Cloudflare-fronted domains certificate-issued under suspicious patterns get scraped and probed. Covered in detail in our CT-log scanner post.
- Customer-consensus promotion — ~10%. Bounce reports from customers using vrfymail in production traffic surface domains we hadn’t seen yet.
The bucket reaches ~5,300 net entries per month and growth tracks Cloudflare’s own adoption curve — every quarter, more disposable operators move behind Cloudflare’s free Email Routing instead of standing up their own MX infrastructure.
FAQ
Why have a separate verdict category at all? Just return disposable if you’re confident enough.
Two reasons. First, the score gives sophisticated handlers a lever — some customers want a softer block on edge cases. Second, the verdict category drives our internal monitoring; we want to know what percentage of “disposable hits” came from MX-corroborated detection vs evidence-stack inference. Those have different operational implications.
Are weighted-disposable verdicts more likely to be false positives?
Slightly. Our calibration target is <0.5% false positives across the whole verdict family. Tier-1 (disposable) hits run lower than that; weighted-disposable (weighted-disposable) runs at the high end of that envelope. If you’re customer-support-allergic to any false-block, branch on score and let weighted hits flow through with a flag instead of a hard reject.
Do Cloudflare-fronted alias-forwarders also use this verdict?
No — alias-forwarders get the alias-forwarder verdict regardless of MX provider. The verdict reflects mechanical behavior, not the hosting layer. The alias forwarder post walks through the mechanism.
Can a domain move from weighted-disposable to disposable?
Yes. If the operator stops fronting their service with Cloudflare and exposes a unique MX, the next refresh re-classifies the domain into the appropriate Tier-2 cluster. Movement in the other direction (Tier-1 to weighted-disposable) is rarer but happens when a previously-fingerprinted operator switches their MX to Cloudflare and we lose the original signal.
What if I want to allow legitimate Cloudflare Email Routing users without allowing temp-mail.org?
That’s already the behavior of the verdict. A legitimate personal domain on Cloudflare Email Routing has no other signals — no disposable blocklist entry, no temp-mail UI, no fingerprint cluster, no customer-consensus reports. It returns result: deliverable with no flag. The weighted-disposable verdict requires the multi-signal stack to fire, not just a Cloudflare MX.
Detect Cloudflare-fronted disposables in 50ms
The signal-stack approach runs on every /v1/check call. Free tier covers 5,000 verifies/month with no card. Get an API key →