isfakemailIsFakeMail
Blog
BlogBuilding a Python Script to Detect Disposable Emails via MX Records

Building a Python Script to Detect Disposable Emails via MX Records

Tired of fake signups? This guide shows you how to build a custom Python script to identify disposable email addresses using MX record resolution and blacklist matching.

6 min read
Building a Python Script to Detect Disposable Emails via MX Records



Most email lists lose value faster than you realize. Average email lists decay at a rate of 25% annually due to inactive users and temporary accounts.

Disposable Email Addresses (DEA) are the primary culprits. They bypass your gated content and leave you with a database full of ghosts that never open a message.

Here is the kicker: a disposable email is technically valid. It passes standard regex checks and SMTP pings because it is a real mailbox, just a temporary one.

If you want to stop the bleed, you need to look at the infrastructure behind the domain. You need to verify if the server on the other end is a legitimate provider or a burner service.

Key Takeaways: The DIY Verification Stack

The Bottom Line

Building a custom verification stack involves three layers of defense.

  1. Syntax Validation: Ensure the string follows RFC standards using email-validator.
  2. DNS Lookup: Use dnspython to query MX records and check for active mail servers.
  3. Blacklist Filtering: Compare domains against a known database of over 30,000 disposable providers.
  4. Fallback Logic: Account for domains that receive mail via A records when MX records are missing.

This approach ensures you only capture high-intent users while filtering out noise at the point of entry.

Prepare Your Environment and Libraries

You need a clean environment to start. This script relies on two main packages to handle the heavy lifting of DNS and syntax checking.

Begin by installing the dnspython Documentation library and the validator utility. Run these commands in your terminal to get your workspace ready.

Prepare Your Environment and Libraries

# Install the necessary Python packages
pip install dnspython email-validator
  • Python 3.x installed and configured.
  • Stable internet connection for DNS queries.
  • Access to port 53 for outbound DNS traffic.
  • A local text file for your domain blacklist.

Validate Email Syntax Beyond Basic Regex

Regex is the most common tool for validation, but it is also the most brittle. It often misses complex RFC-compliant addresses that are perfectly functional.

A disposable email is a valid email address and will successfully pass Python regex or SMTP checks.

Instead of writing a 100-character regex string, use a dedicated library. This handles the edge cases of TLDs and special characters without breaking your validation logic.

from email_validator import validate_email, EmailNotValidError

def check_syntax(email_address):
    try:
        # Check syntax and deliverability
        validation = validate_email(email_address, check_deliverability=False)
        return validation.email
    except EmailNotValidError as e:
        print(f"Invalid: {str(e)}")
        return None

Tip: Always perform syntax validation first to avoid wasting network resources on DNS lookups for gibberish strings.

Resolve MX Records to Identify Active Mail Servers

An MX (Mail Exchange) record tells you where to send mail for a domain. If a domain has no MX record, it usually cannot receive mail unless it falls back to an A record.

According to RFC 5321 - SMTP, mail servers should try the A record if the MX lookup fails. Extract the domain and query both to be thorough.

Resolve MX Records to Identify Active Mail Servers

Here's a walkthrough that covers the key steps:

import dns.resolver

def get_mx_records(domain):
    try:
        # Attempt to resolve MX records
        answers = dns.resolver.resolve(domain, 'MX')
        return [str(r.exchange) for r in answers]
    except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
        # Fallback to A record check
        try:
            dns.resolver.resolve(domain, 'A')
            return [domain]
        except:
            return []

This logic identifies if the domain has the infrastructure to support communication. It separates real companies from parked domains used for squatting.

Cross-Reference Against Known Disposable Domains

Resolving the DNS is only half the battle. You must check if the mail server belongs to a known burner provider like mail.mailinator.com or other temporary services.

You can find community-maintained lists like the Disposable Email Domains List (GitHub) to power your filter. Comparing the domain against these blacklists is your strongest defense.

import json

def is_disposable(domain, blacklist_path='disposable.json'):
    with open(blacklist_path, 'r') as f:
        blacklist = json.load(f)

    # Check if the domain or its MX host is in the list
    if domain in blacklist:
        return True
    return False
  • If the domain matches a blacklist entry, then block the signup.
  • If the MX host contains keywords like '10min' or 'tempmail', then flag the account.
  • If the domain is a major provider like Gmail or Outlook, then bypass the check.

Optional: SMTP Handshake for Deep Verification

For deep verification, you can perform an SMTP handshake. This involves connecting to the mail server and asking if the specific mailbox exists without actually sending a message.

The server returns a 250 status code if the recipient is valid. This provides a high level of certainty for your user data.

Pitfall: Many modern email service providers block SMTP probes to prevent email harvesting. This can result in false negatives or IP blacklisting for your server.

import smtplib

def verify_mailbox(mx_host, email):
    try:
        server = smtplib.SMTP(timeout=10)
        server.connect(mx_host)
        server.helo('yourdomain.com')
        server.mail('me@yourdomain.com')
        code, message = server.rcpt(email)
        server.quit()
        return code == 250
    except Exception:
        return False

When to Use a Custom Script vs. a Paid API

Maintaining a custom script is a commitment. You have to update the domain lists manually as new disposable providers emerge every day.

Services like IsFakeMail automate this process. They provide a real-time API with a database of over 187,000 known disposable domains updated continuously without your intervention.

When to Use a Custom Script vs. a Paid API

Feature Custom Python Script IsFakeMail API
Price Free (Labor cost) Free
Maintenance Manual list updates Fully automated
Accuracy Medium (Static lists) High (Real-time detection)
Speed Depends on DNS latency Under 50ms
Best For Small scale / Hobbyists SaaS / High-growth apps

Using a professional tool avoids the common IP reputation issues found in local SMTP probes. It offloads the infrastructure burden while keeping your signups clean.

Verify and Test Your Script

Before deploying your script to production, you must verify the logic. Test it against different scenarios to ensure it distinguishes between friend and foe.

Sarah, a developer at a growing SaaS, once deployed a script that accidentally blocked all Gmail addresses because of a regex error. Her team lost hundreds of trials before catching the bug.

  • Run the script against a known legitimate address like example@gmail.com.
  • Test against a known burner like test@mailinator.com to confirm detection.
  • Verify that DNS resolution timeouts are handled gracefully without crashing.
  • Confirm that A record fallback works for domains without explicit MX records.

Automating Your Email Hygiene

Validating emails via MX records is a fundamental step in protecting your platform. By combining syntax checks, DNS resolution, and domain blacklists, you drastically reduce the volume of fake accounts.

Integrate these checks directly into your signup form or background processing worker. Start cleaning your list today to improve your deliverability and marketing ROI.

Frequently Asked Questions

Why do some domains have no MX records?

Some domains use their primary A record as the mail server. This is a legacy standard defined in RFC 5321 that your script must account for to avoid false negatives.

What is a catch-all server?

A catch-all server accepts mail for any username at its domain. In these cases, the SMTP handshake will always return a 250 code, making individual mailbox verification impossible.

How often should I update my domain blacklist?

New disposable domains appear daily. If you are using a local script, you should update your source data at least once a week to maintain high accuracy.

Can I use these checks for front-end validation?

DNS queries are slow and can delay the user experience. It is better to perform these checks on the back-end or use a fast API like IsFakeMail for real-time front-end feedback.

Building a Python Script to Detect Disposable Emails via MX Records