DEV Community

DevToolsmith
DevToolsmith

Posted on

Why Your Emails Bounce (and How to Catch Bad Addresses Before You Hit Send)

Email bounces feel like a small annoyance until you realize they quietly damage every send that follows. This is a practical look at why lists go bad and how to validate them before a campaign, with a simple approach you can run on a single address or a whole CSV.

The problem: one dirty send taxes all the others

When you email an address that doesn't exist, the receiving server returns a hard bounce. A few of those is normal. But when bounces cluster, like right after you import a list or run a big campaign, mailbox providers (Gmail, Outlook, Yahoo) read it as a signal that you don't maintain your list. Their response is to filter more of your mail, including the messages going to real, engaged subscribers.

So the cost of bad addresses isn't just the wasted send. It's a reputation hit that pushes your good mail toward spam folders for weeks. Newsletter operators see open rates collapse. SaaS founders watch onboarding emails miss the people who just signed up. E-commerce stores lose order confirmations to the void.

The good news: most bad addresses are detectable before you send.

The four things that break a list

A typical list accumulates four kinds of bad addresses:

  1. Bad syntax. Missing the @, a trailing dot, illegal characters. The easiest to catch.
  2. Typo'd domains. People fat-finger "gmial.com", "hotmial.com", "yahooo.com". The address is syntactically valid but the domain is wrong, so it bounces.
  3. Dead or non-receiving domains. The domain has no mail server (no MX record), so nothing can be delivered.
  4. Disposable / temporary inboxes. Sign-up throwaways that exist for ten minutes. They inflate your list and never engage.

How to validate, step by step

A solid pre-send check runs these stages in order, cheapest first:

  1. Syntax check. Confirm the address is well-formed before doing anything network-related.
  2. Typo / domain heuristic. Compare the domain against common providers and flag near-misses like "gmial.com" so they can be corrected, not discarded.
  3. MX record probe. Look up the domain's mail servers. No MX record means no mailbox can receive mail there.
  4. Disposable check. Match the domain against known throwaway providers and flag it as risky.

If you want to sketch the MX step yourself, the core lookup is just a few lines in Node:

import { promises as dns } from "node:dns";

async function domainCanReceiveMail(email) {
  const domain = email.split("@")[1];
  if (!domain) return false;
  try {
    const mx = await dns.resolveMx(domain);
    return mx.length > 0;
  } catch {
    return false; // no MX record = cannot receive mail
  }
}

await domainCanReceiveMail("hello@gmial.com"); // false
Enter fullscreen mode Exit fullscreen mode

That snippet covers one stage. A real validator layers syntax rules, a typo dictionary, the MX probe, and a disposable-domain list, then runs the whole thing across every row of your CSV so you can clean an entire list in one pass rather than checking addresses one at a time.

Make it a habit, not a fire drill

The mistake most senders make is only cleaning a list after the bounces have already done damage. By then the reputation hit is in motion. Treat validation like a pre-flight check: scrub right before any large or important send, and re-scrub lists that have been sitting unused for months (addresses decay over time as people change jobs and abandon inboxes).

If you'd rather not wire the stages together yourself, EmailGuard runs all four, syntax, typo detection, MX probing, and disposable flagging, and accepts either a single address or a CSV upload for bulk verification. It's built to be a faster, simpler way to do the pre-send scrub without standing up a whole pipeline.

Either way, the principle holds: clean the list before you send, and you protect the deliverability of everything that comes after.



Full disclosure: I build EmailGuard, a fast email validation tool that checks syntax, MX records, typos and disposable addresses, in bulk from a CSV. It is free to try at https://emailguard.dev.

Top comments (0)