emailverifier.dev
Posts

Why a Verified Email Address Can Still Bounce

| 6 min read | Usama Ejaz
A three-stage timeline shows an email passing verification, moving through a mail server, and returning as a failed delivery.

A verified email address can still bounce because verification and delivery are separate observations made at different times. Verification records the address, domain, and mailbox evidence available during the check. A later send adds the sender, message, route, mailbox state, and receiving server's current policy. A successful check lowers uncertainty. It does not reserve future delivery.

The apparent contradiction disappears when you keep those observations in order. I use three clocks: when the address was checked, when the message was handed to SMTP, and when the final delivery evidence arrived.

Follow one address through three clocks

This hypothetical trace shows a message that passed a pre-send check, received two successful SMTP replies, and still produced a later failure:

08:00:00 verification  status=deliverable checked_at=2026-10-22T08:00:00Z
08:14:02 smtp          RCPT TO:<ava@team.example>  250 2.1.5 OK
08:14:03 smtp          end-of-DATA                250 2.0.0 queued
08:16:41 dsn           Action: failed             Status: 5.1.1

Nothing in that sequence requires the earlier check to guarantee the later outcome. Each line answers a narrower question.

Clock 1: what did verification establish?

A verification result is timestamped evidence. Depending on the result, it may include syntax, DNS mail routing, provider characteristics, SMTP behavior, and risk signals. The exact SMTP boundary matters: some receiving systems confirm a recipient, some defer the decision, and catch-all domains may accept both real and invented local parts.

That is why emailverifier.dev returns a technical status, recommended action, and the signals behind the decision. The result is designed for a product decision at that moment. It is not proof that a person controls the inbox or that every future message will be accepted.

Clock 2: what did the receiving server accept?

An SMTP 250 reply has to be read at the command that produced it. After RCPT TO, it means the server accepted and stored the forward path for this transaction. The server can still reject the message after seeing its content, size, authentication, or policy context.

A final 250 after the message data is stronger, but it is still not an inbox receipt. RFC 5321 says that reply transfers responsibility to the receiving server for delivery or relay. It also says some later delivery failures are unavoidable and must be reported to the envelope return path.

The existing SMTP verification walkthrough owns the probe sequence. The important distinction here is timing: recipient acceptance during a check and message acceptance during a send are different transactions.

Clock 3: what did the delivery report say?

A standards-shaped delivery status notification, or DSN, carries per-recipient fields. RFC 3464 defines fields such as Final-Recipient, Action, Status, and Diagnostic-Code. Read them together.

Action: failed says the reporting mail system stopped trying for that recipient. Status: 5.1.1 says the destination mailbox address does not exist. By contrast, Status: 4.2.2 means the mailbox is full and is classified as a persistent temporary failure in RFC 3463.

Those reports describe the later delivery attempt. They should not be flattened into the same field as the earlier verification result.

Why can the evidence change?

Several mechanisms can produce a real bounce after a reasonable pre-send result:

  • The mailbox changed. It was removed, disabled, moved without forwarding, or reached a temporary quota after the check.
  • The receiver delayed recipient validation. A server may accept the recipient during one stage and decide later, including after message data or during downstream delivery.
  • The message introduced new facts. Size, content, sender authentication, source reputation, rate limits, and authorization policy do not exist in a mailbox-only check.
  • The route or destination had a temporary failure. DNS trouble, connection failures, congestion, and unavailable systems can outlive the sender's retry window without proving the address is permanently invalid.
  • The original result carried uncertainty. Catch-all behavior, policy blocks, timeouts, and inconclusive SMTP replies should remain visible rather than being presented as certain mailbox existence.

The strongest fair objection is simple: if a check says “deliverable” and the next send gets 5.1.1, wasn't the check wrong? It may have missed the receiver's real state, so investigate the timestamps, signals, exact address, and SMTP transcript. But a disagreement alone does not identify the cause. A catch-all response, a mailbox removed between events, or a recipient decision deferred until later can produce the same surface symptom.

Which result should change the address state?

Newer evidence matters, but only within its scope. I use these precedence rules:

  • A later recipient-specific permanent failure such as 5.1.1 or 5.1.6 is strong evidence to suppress future sends to that exact address.
  • A 4.x.x status or Action: delayed belongs in retry and delivery state, not a permanent invalid-address bucket.
  • A policy or security failure such as 5.7.1 can be permanent for that message or sender while saying little about whether the mailbox exists.
  • A timeout, missing report, or unparseable reply stays inconclusive. Silence is not a mailbox verdict.

The hard-bounce versus soft-bounce guide goes deeper on DSN classification. The useful boundary here is that later delivery evidence can update future sending policy without rewriting history or pretending the verification never happened.

Store the history, not one mutable Boolean

A field such as email_valid: true cannot explain a disagreement. Keep the two events and their evidence. This hypothetical record is enough to reproduce the decision:

{
  "email": "ava@team.example",
  "verification": {
    "checked_at": "2026-10-22T08:00:00Z",
    "status": "deliverable",
    "action": "accept",
    "signals": ["syntax_ok", "mail_route_found", "smtp_accepted"]
  },
  "delivery": {
    "attempted_at": "2026-10-22T08:14:02Z",
    "phase": "post_acceptance_dsn",
    "final_smtp_reply": "250 2.0.0 queued",
    "dsn": {
      "action": "failed",
      "status": "5.1.1",
      "final_recipient": "ava@team.example",
      "diagnostic_code": "smtp; 550 5.1.1 mailbox unavailable"
    }
  }
}

Use the verification event to decide whether to accept, flag, or retry an address before sending. Use the delivery event to decide whether to retry the message, suppress the recipient, or investigate sender policy. The production API result guide shows how to preserve confirmed failures, risk signals, and unknown results without collapsing them into one branch.

Reverification still helps when old evidence is about to support a meaningful decision, but it does not replace bounce processing. The reverification guide owns that timing policy.

A verified address that later bounces is not a paradox. It is a sequence. Keep the timestamps, the SMTP stage, the DSN fields, and the original signals, then let the newest relevant evidence change only the state it actually supports.

Continue reading