How to Block Disposable Email Signups on Your Site
Blocking disposable signups is a mix of a domain blocklist, an MX check, and sometimes a validation API. Here is how each works, and the false positives to weigh before you ship it.
Blocking disposable email signups requires choosing a detection approach and accepting the trade-offs that come with it. The three main tools are a domain blocklist, an MX check, and a third-party validation API. Each catches different things, costs different amounts to run, and carries a different false-positive risk.
This guide explains how each approach works at the implementation level, what sources you need, and what to weigh before you turn any of it on. It is written for developers building or modifying a signup flow.
Key takeaways
- A domain blocklist is the simplest starting point: the open-source disposable-email-domains list covers thousands of known throwaway domains and is used in production by services including PyPI.
- MX checks add a second layer: domains that have no MX record configured cannot receive mail and should be rejected; syntax validation should run first so you never issue a DNS query for a malformed address.
- Detection APIs correlate multiple signals (shared MX infrastructure, missing SPF/DKIM/DMARC, domain age) and can catch disposable addresses that blocklists miss, but they add latency, cost, and an external dependency.
- Blocklists are estimated to cover only 60-80% of disposable addresses; new throwaway domains are registered continuously and no static list stays current on its own without regular updates.
- False positives are the key trade-off: privacy-focused aliases, corporate catch-alls, and some university addresses can all look disposable to an automated check, and blocking them turns away real users.
Decide first whether you should block at all
The case for blocking disposable emails is straightforward: throwaway signups inflate user counts, bypass trial limits, and generate abuse without accountability. Many products legitimately want to restrict signups to addresses users will read.
The case against is less often written down. A blanket block on disposable or aliased addresses also catches real users. Privacy-conscious people routinely use email aliasing services like SimpleLogin, Apple's Hide My Email, or Fastmail's masked addresses. Some developers use disposable inboxes specifically to test your own signup flow. University and company catch-all domains sometimes match the same infrastructure signals that disposable providers use. A tightly tuned block keeps out abuse; an overly broad one turns away a measurable slice of legitimate signups.
The question to settle before writing any code is: what behavior are you trying to prevent? If the answer is disposable addresses being used to harvest free trials, a blocklist pass is probably sufficient. If the answer is low-quality signups more broadly, email alone is a weak signal and you may be better served by behavioural checks or confirmed opt-in requirements. Building a disposable-email check that is too aggressive is easy to do and hard to walk back without frustrating the users it falsely rejected.
Once you have decided the check is worth adding, the three approaches below compose well together. Run them in order: syntax first, then domain list, then MX, then an API if you need the extra coverage.
Approach 1: a domain blocklist
The fastest check is to compare the domain part of the submitted address against a list of known disposable providers.
The most widely used open-source resource for this is the disposable-email-domains repository, which has over 5,100 GitHub stars and is used in production by services including PyPI. PyPI explicitly prohibits account creation using known "throw-away" email domains, and the project's README describes the list as domains "often used to register dummy users to spam or abuse services." The list ships as a plain text file with one domain per line.
Consuming it in code is simple. At build time or on a cron, fetch the raw file and load it into a Set:
// At startup or on a scheduled refresh
const res = await fetch(
'https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/main/disposable_email_blocklist.conf'
);
const raw = await res.text();
const blocklist = new Set(raw.split('\n').map(s => s.trim()).filter(Boolean));
function isBlocklisted(email: string): boolean {
const domain = email.split('@')[1]?.toLowerCase();
return domain ? blocklist.has(domain) : false;
}
Two practical notes for production use. First, the list changes; new disposable domains are registered continuously, so a stale snapshot pulled once at deploy time will miss recent additions. Schedule a refresh at least daily. Second, the list is domain-based only: it identifies known throwaway providers, it does not attempt to detect disposable addresses from arbitrary structural patterns in the address itself. An address at an unknown or freshly registered domain will pass this check regardless of what the local part looks like.
A domain blocklist is the right first pass. It is fast (a Set lookup), free, requires no network call at request time, and catches the large established providers. It is not sufficient on its own, which is why the next two approaches exist.
Approach 2: MX and syntax checks
After the blocklist, verify that the domain can receive mail. This catches newly registered throwaway domains that have not yet appeared on any list.
Start with syntax. RFC 5321, the Internet Standard for SMTP, defines the format of a valid email address and how mail servers use MX records to route messages between domains. A well-formed address has a local part, an "@", and a domain. Reject anything that fails this check before issuing any DNS query. A simple regex covers most cases:
function hasValidSyntax(email: string): boolean {
// Covers the common case; not a full RFC 5321 parser
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
Then check for an MX record. RFC 5321 specifies that mail is routed via the MX records of the recipient's domain. A domain with no MX record cannot receive email, and submitting such an address is either a typo or an attempt to use an invalid address. In Node.js:
import { promises as dns } from 'dns';
async function hasMxRecord(email: string): Promise<boolean> {
const domain = email.split('@')[1];
if (!domain) return false;
try {
const records = await dns.resolveMx(domain);
return records.length > 0;
} catch {
return false; // NXDOMAIN or no MX
}
}
An MX check is cheap: one DNS query per unique domain, and you can cache results for a domain for several minutes to avoid redundant lookups on burst signups. Its limits are the same as the blocklist in a different direction: many legitimate personal domains and some smaller hosting providers have odd DNS setups, and an MX check will fail them if they are temporarily unreachable at check time. Add a short timeout and treat DNS errors as a soft pass rather than a hard reject unless you have reason to be strict.
The MX check does not tell you whether the domain is a disposable provider; it only tells you whether the domain is configured to accept mail at all. Combine it with the blocklist rather than substituting one for the other.
Approach 3: a detection API
If the blocklist and MX check do not provide enough coverage, a third-party validation API adds more signals.
Services in this category correlate infrastructure-level characteristics to score an address. The Castle Security blog describes MX records as "one of the strongest infrastructure signals": disposable providers often share MX host infrastructure across many domains, and their domains tend to lack SPF, DKIM, and DMARC records and to be "often newly registered." A detection service can flag a domain that is not yet on any static blocklist because it exhibits these infrastructure patterns.
The coverage difference matters. Well-maintained blocklists cover an estimated 60-80% of disposable addresses; new throwaway domains are registered faster than lists can track them. TrustPath, for example, states it tracks 800+ providers and 380,000+ domains with a stated false-positive rate below 1%, and notes the 60-80% coverage gap for static lists specifically. Whether those figures hold for your user base depends on your traffic; numbers from a vendor should be treated as directional, not guaranteed.
Adding a third-party API call carries three trade-offs that should be weighed before you commit to one.
Latency is the first: an external HTTP call in the critical path of a signup form adds measurable time. Cache validated domains for a reasonable window, and build in a fallback so a slow or failed API response does not block signups entirely.
Cost is the second: most validation APIs meter by request, and at scale the cost can exceed the value of the signups you are blocking, particularly if your user base is low-risk.
Dependency is the third: an external service in your signup path can go down. Your form should degrade gracefully. If the API is unreachable, decide in advance whether that is a hard reject or a soft pass, and code accordingly.
An API makes sense when you have tried the blocklist and MX check and still see a volume of disposable signups that justifies the additional cost and complexity. For most forms, the first two approaches together are sufficient.
Testing your rule
Before deploying any of these checks to production, test them against real cases.
For the happy path, use the email validator tool to spot-check whether your implementation accepts addresses you intend to allow. For the blocking path, test against a real disposable address: open an inbox at TempMailSpot and submit that address to your own form. If the block fires, you are catching the right target; if it passes, something in your implementation needs attention.
Also test the false-positive cases explicitly. Try an Apple Hide My Email address (which uses apple.com infrastructure), a plus-aliased Gmail address, and a custom domain that has minimal DNS records. All three should pass a well-calibrated check. If any of them trip your rule, your block is too broad.
For load testing the MX check, make sure your DNS cache is working. A check that issues a fresh DNS lookup on every request will be slow under burst load. Cache the result per domain for at least a minute.
The email delivery testing guide covers the complementary problem: once you have a signup flow that accepts addresses, how to verify that the emails you send are delivered. Running both tests together gives you confidence in both the filter and the delivery path.
Blocking disposable email signups comes down to layering three checks: a domain blocklist to catch known throwaway providers quickly, an MX check to reject domains that cannot receive mail at all, and optionally a detection API for the 20-40% of disposable addresses that blocklists miss.
The decision to add any of these should start with what you are trying to prevent. A blocklist plus MX check is straightforward to implement, low-latency, and free to run. An API adds coverage at the cost of latency, dependency, and money. None of these approaches is perfect, and the most important test to run is the false-positive one: submit the kinds of addresses your real users might use before you ship to production.
If you are on the other side of this equation, using a disposable inbox to keep spam out of a real address, TempMailSpot keeps your primary inbox clean without the friction of managing throwaway accounts.
Frequently asked questions
Sources
- disposable-email-domains (GitHub), disposable-email-domains: a list of disposable and temporary email address domains (opens in new tab) (2014)
- disposable-email-domains (GitHub README), disposable-email-domains/README.md at main (opens in new tab) (2026)
- Castle Security Blog, How to detect disposable email domains without relying on 3rd party APIs and lists (opens in new tab) (2025)
- TrustPath, How to Detect Disposable Email Addresses: A Technical Guide (opens in new tab) (2024)
- IETF / RFC Editor, RFC 5321: Simple Mail Transfer Protocol (opens in new tab) (2008)
Recommended privacy tools
Independent privacy tools that complement a disposable inbox.
NordVPN
Encrypted tunneling across thousands of servers with an audited no-logs policy. For private browsing on untrusted networks.
Learn MoreExpressVPN
Consistently fast servers in 90 plus countries, an audited no-logs policy, and a clean app on every platform.
Learn MoreSurfshark
Unlimited devices on one plan, with ad and tracker blocking built in. The budget pick that does not feel budget.
Learn More