Skip to content

feat: detect domains with no MX records #7

Description

@mdesoto

Context

A domain with no MX (mail exchange) records cannot receive email. If a user signs up with user@no-mail-server.com and that domain has no MX records, the email address is effectively invalid — the confirmation email will never arrive.

This is a lightweight DNS check (not SMTP verification, not mailbox probing). It catches:

  • Completely fake domains
  • Parked domains
  • Domains that exist but aren't configured for email

Proposed behavior

Signal name

noMxRecord

Detection

Perform a DNS MX lookup on the domain. If no MX records are found, flag it:

const result = await guard.verify('user@no-mail-server.com');
// {
//     isMatch: true,
//     matchedOn: ['noMxRecord'],
//     domain: 'no-mail-server.com',
//     ...
// }

Configuration

const guard = await BurnerGuard.create({
    checkMxRecords: false,      // default: false (opt-in, requires network)
    mxLookupTimeout: 5000,      // DNS timeout in ms (default: 5000)
    treatNoMxAsMatch: true       // default: true (no MX = match)
});

Opt-in because:

  • Requires a network call (DNS), which breaks the offline/sync contract for static mode
  • Adds latency to verify()
  • May not be available in all environments (browsers, some edge runtimes)

Implementation notes

  • Use dns.resolveMx() from Node.js dns/promises — dynamically imported like the fs module
  • Cache results per domain to avoid repeated DNS lookups within the same instance
  • Consider fallback: if DNS lookup times out, don't flag (fail open, not closed)
  • Some domains use an A record as an implicit MX fallback (RFC 5321 §5.1) — decide whether to honor this
  • Not available in browser environments — should gracefully skip when dns module isn't available

Interaction with other signals

A domain could trigger both blocklist and noMxRecord. Both appear in matchedOn.

Acceptance criteria

  • DNS MX lookup via dynamically imported dns/promises
  • noMxRecord signal in matchedOn
  • checkMxRecords opt-in config with timeout and match behavior options
  • Per-domain MX result caching within the instance
  • Graceful skip in environments without dns module (browsers)
  • Timeout handling (fail open)
  • Tests covering: domain with MX, domain without MX, timeout, caching, browser fallback
  • README section explaining MX detection as an opt-in network-dependent feature

Priority: 🟡 Medium — cheap signal that catches fake domains, but requires network

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions