Email Bounce and Rejection Reasons
When an email cannot be delivered, the receiving mail server returns a failure reason. Different providers surface these in different ways. Truncus normalizes them into deterministic terminal states.
Terminal states
| Status | Meaning |
|---|---|
delivered | Mailbox accepted the message |
bounced | Delivery failed after transport attempt |
rejected | Message rejected before delivery attempt |
Failure reasons
| Reason | Meaning | Typical SMTP code | Recommended action |
|---|---|---|---|
mailbox_full | Inbox storage exceeded | 552 | Retry later |
user_unknown | Address does not exist | 550 | Remove address |
domain_not_found | Domain DNS unresolvable | NXDOMAIN | Remove address |
spam_blocked | Rejected by spam filter | 554 | Check domain reputation |
policy_block | Domain policy rejection | 550 | Review sender config |
temporary_failure | Transient delivery issue | 451 | Retry later |
connection_timeout | Recipient server unreachable | — | Retry later |
suppression_list | Address previously bounced | — | Do not retry |
mailbox_full
The recipient mailbox has exceeded its storage quota.
Typical SMTP response:
552 5.2.2 Mailbox full
Truncus response:
{ "status": "bounced", "reason": "mailbox_full" }
This is a soft bounce — a temporary condition. Retry after a delay. If it persists after several retries, treat the address as unreachable.
user_unknown
The email address does not exist on the recipient server.
Typical SMTP response:
550 5.1.1 The email account that you tried to reach does not exist
Truncus response:
{ "status": "bounced", "reason": "user_unknown" }
This is a hard bounce. Remove the address from your system and do not retry. Continuing to send to non-existent addresses damages your domain reputation.
domain_not_found
The recipient domain has no valid MX record or is not resolvable in DNS.
Common causes: typo in the domain part of the email address, domain expired, domain deleted.
Truncus response:
{ "status": "bounced", "reason": "domain_not_found" }
Treat as a hard bounce. Remove the address.
spam_blocked
The message was rejected by the recipient server's spam filter.
Typical SMTP response:
554 5.7.1 Message rejected due to policy
Truncus response:
{ "status": "bounced", "reason": "spam_blocked" }
Investigate your sending domain's reputation. Check your DKIM/SPF/DMARC configuration. Review message content for spam triggers.
suppression_list
The address is on Truncus's suppression list — meaning it previously generated a hard bounce or spam complaint.
Truncus blocks sending to suppressed addresses to protect your domain reputation.
Truncus response:
{ "status": "rejected", "reason": "suppression_list" }
Do not retry. Contact your recipient to verify their address if needed.
temporary_failure
The receiving server returned a transient error.
Typical SMTP response:
451 4.7.1 Try again later
Truncus response:
{ "status": "bounced", "reason": "temporary_failure" }
This is a soft bounce. Retry after a delay.
Handling failures programmatically
const response = await truncus.emails.send({ to, from, subject, html })
switch (response.status) {
case 'delivered':
// record success
break
case 'bounced':
if (['user_unknown', 'domain_not_found'].includes(response.reason)) {
// hard bounce — remove address permanently
await removeEmailAddress(to)
} else {
// soft bounce — schedule retry
await scheduleRetry(to, response.reason)
}
break
case 'rejected':
if (response.reason === 'suppression_list') {
// do not retry — address is blocked
await markAddressSuppressed(to)
}
break
}
Bounce types
Hard bounce: permanent delivery failure. The address is invalid or permanently unreachable. Remove from your list immediately. Continuing to send to hard-bounced addresses degrades your sender reputation.
Soft bounce: temporary failure. The address is valid but temporarily unreachable. Retry after a delay, but set a retry limit.
| Reason | Type |
|---|---|
mailbox_full | Soft |
temporary_failure | Soft |
connection_timeout | Soft |
user_unknown | Hard |
domain_not_found | Hard |
spam_blocked | Hard |
suppression_list | Rejected (do not retry) |