Skip to main content

Validate email and domain (MX, SPF, DMARC, DKIM, SSL)

Project description

email-domain-validator

Validate an email address with syntax normalization, plus domain-level DNS checks: MX, SPF, DMARC, DKIM, and SSL/TLS certificate inspection.

This package reports each check independently. It does not produce a single global decision like 'valid' or 'invalid' for fraud, abuse, or trust. Treat the output as verification signals that can feed your own risk scoring, allow/deny rules, or enrichment pipeline.

Install

Requires: Python >= 3.14

pip install email-domain-validator

Quick start

CLI

email-domain-validator user@example.com

CLI options

  • --timeout N: per-check timeout in seconds for DNS and TLS operations (default: 5)
  • --no-mx, --no-spf, --no-dmarc, --no-dkim, --no-ssl: skip one check
  • --compact: print JSON output without indentation

Library

from email_domain_validator import validate_email_and_domain

result = validate_email_and_domain('user@example.com')
print(result.email_valid, result.mx.valid, result.spf.valid)

By default, all optional checks run. Use ValidationOptions to set timeout and enable/disable checks (run_mx, run_spf, run_dmarc, run_dkim, run_ssl).

from email_domain_validator import ValidationOptions, validate_email_and_domain

result = validate_email_and_domain(
    'user@example.com',
    options=ValidationOptions(run_dkim=False, run_ssl=False),
)
print(result.to_dict())

Execution behavior

  • Email syntax normalization always runs first and cannot be disabled.
  • MX runs only when email_valid=True (that is, syntax normalization succeeds).
  • SPF, DMARC, DKIM, and SSL run against the domain.

Checks

The checks below follow widely used email-authentication and transport conventions, while keeping results practical for application logic and risk pipelines.

Email (syntax and normalization)

Uses python-email-validator for syntax validation and normalized email extraction, equivalent to: validate_email(email, check_deliverability=False).

If syntax validation raises an exception, the check result is returned as None. This check is always executed and cannot be disabled.

This stage helps ensure downstream DNS and policy checks run against a clean, normalized address form instead of raw user input.

MX

Verifies whether the domain publishes mail-exchanger records using python-email-validator, equivalent to: validate_email(email, check_deliverability=True, timeout=timeout).

The report includes discovered MX hosts when available. If MX lookup fails or the email is invalid, the MX check is marked invalid. If lookup succeeds but no hosts are returned, the result is valid=True with records=[].

Operationally, this is a deliverability-oriented signal: domains with clear MX configuration are usually better candidates for transactional email workflows.

SPF

Looks for a TXT record that starts with v=spf1. If no SPF record is found, the SPF check is marked invalid. When found, additional SPF checks are performed, including:

  • qualifier analysis for broad/catch-all sender matching behavior
  • detection of ptr deprecated mechanism
  • extraction and validation of declared IPv4/IPv6 addresses
  • recursive extraction of include domains (maximum 10 DNS lookups)

This helps you identify overly permissive sender authorization, stale network declarations, and inheritance patterns across included sender policies.

DMARC

Looks up the DMARC policy record at _dmarc.<domain> and verifies the expected v=DMARC1 marker at record start.

DMARC presence is a strong governance signal because it indicates the domain has published an authentication policy entry point, even when you still need higher level business logic for final trust decisions.

DKIM

Checks for DKIM records at <selector>._domainkey.<domain>. The validator tries common selectors from DKIM_SELECTORS and stops on the first valid record found.

In the worst case, this performs one DNS TXT lookup per selector candidate until a match is found (or candidates are exhausted).

Because selector usage varies by provider and deployment age, this check targets commonly used selectors as a practical "likely configured" signal. It validates selector/key record presence at the DNS level and does not verify end-to-end DKIM message signatures.

SSL/TLS

Inspects the domain certificate and reports connection metadata, including host IP, TLS probe version label, and certificate expiration status.

Treat this as transport posture context for your domain profile, not as proof of mail-channel security by itself. The SSL check fetches and parses the presented certificate for inspection; it does not perform strict hostname/chain trust validation.

Result models

Results are returned as dataclasses (for example: EmailDomainValidationResult, SPFVerificationReport). See src/models.py for the full model list.

Further validation

Domain-level authentication checks are strong signals, but they are not a full identity or abuse guarantee by themselves.

For stronger decisions, combine these results with disposable-domain and role-based address intelligence, plus your own context-specific policies.

Examples:

Contributing

See CONTRIBUTING.md for local setup, test commands, and change submission workflow.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

email_domain_validator-0.1.0.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

email_domain_validator-0.1.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file email_domain_validator-0.1.0.tar.gz.

File metadata

  • Download URL: email_domain_validator-0.1.0.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for email_domain_validator-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8c064ef0f36a9d4b07205ed3b92a69403dff149f1c03dfcf4a0131db239e734d
MD5 770fcc54434678f60e9017d26a852776
BLAKE2b-256 8dd60b8ac0086885319c33d77cdc426f07caad3410185e70b51261a19d2f69b2

See more details on using hashes here.

File details

Details for the file email_domain_validator-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: email_domain_validator-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for email_domain_validator-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 640a572f6f979dd0ecfeee7ae697a7a39086860395f28b0776756f682b522410
MD5 170d9ca4cb9a8c563fe3fb333e9334e8
BLAKE2b-256 482060f749a85715aa9832148ddb359da9f82d109b8b5ad3751897f683e133be

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page