Hard and soft bounces are not two sizes of the same thing

Every sending platform splits bounces into two columns: hard and soft. The split looks like a severity scale - one is bad, the other is less bad. It is not a severity scale. The two columns describe two different objects: a hard bounce is a statement about the mailbox, and a soft bounce is a statement about the moment.

What the codes actually say

ResponseWhat it is aboutWhat it licenses you to do
550 5.1.1 user unknownThe mailboxRetire the address. The server looked and could not find it
550 5.1.2 / 5.4.1 - domain or host not foundThe domain, not the personRetire the domain decision, then re-check whether the employer changed - 23% of contacts change jobs in a year (ZoomInfo, 2025)
552 / 452 4.2.2 mailbox fullThe momentNothing. Retry later; a full mailbox is a working mailbox with a storage problem
421 / 450 greylisting and rate limitsYour probing patternSlow down and re-probe. The address was never judged
5.x.x from a relay in the middleThe relayNothing about the recipient. A block on the path is not a verdict on the mailbox

Only the first two rows are statements about whether the address can exist. The rest are statements about the attempt.

The expensive habit: scrubbing the moment as if it were the mailbox

Most pipelines act on a single boolean - did the send fail - and delete the contact. That turns three different events into one: a mailbox that never existed, a mailbox that was full on Tuesday, and a probe that was rate-limited. Two of the three deletes cost you a live contact.

The rule that survives contact with reality

  1. Retire only on an explicit negative answer. An address leaves the list when a server said the mailbox does not exist - not when the attempt failed.
  2. Keep unresolved as its own state, with the date. A timeout or a rate limit with no timestamp is indistinguishable from a mailbox that died six months later.
  3. Re-probe before the send, not on a calendar. The reason to re-check is that a batch is going out; a monthly scrub checks dates, not deliverability.
  4. Watch the soft-bounce pile for a pattern. Repeated soft bounces on one domain usually mean a blocked path or an aggressive gateway, not a list of dead people.
  5. Log the domain-level failures separately. "Domain gone" and "person gone" lead to different fixes, and only one of them means find a new contact at the same company.

How this looks in a check that is already running

TAPAC probes the mailbox inside the search that found the contact, so a result arrives with one of three states rather than a boolean: deliverable, undeliverable, or unknown for catch-all domains - plus the time of the call and the source page or profile the address came from. That timestamp is what separates a contact that should be retried from one that should be retired.

npx -y @tapacapi/mcp        # tools: tapac_find_contacts, tapac_status
# or hosted: https://tapacapi.com/mcp
# or REST:   POST https://tapacapi.com/v1/contacts/search

Checked contacts carry a published 2-5% bounce rate against 10-35% for static, resold databases; TAPAC is pay-per-use at $0.10-0.50 per contact with 100 free searches.

Related: what a verification log should contain, when the mail server never answers, and cleaning a list as maintenance, not a cure.

← Back to TAPAC