Module 7 · Lesson 14 of 25

How KumoMTA classifies bounces

Part of KumoMTA: High-Volume Sending Engine — Bounce Processing & FBL Handling.

When a remote server rejects your message, KumoMTA captures:

  • SMTP code (4xx, 5xx).
  • Enhanced status code (5.1.1, 5.7.1, etc.).
  • Diagnostic text from the remote.

It runs the diagnostic through its bounce classifier (ships with patterns for Gmail, Yahoo, MS, ProtonMail, etc.) and assigns a category:

Category Action
InvalidRecipient Remove from list immediately
ContentRejected Review content, suppress only if persistent
PolicyRejected IP/domain reputation issue — investigate, don't blame the list
Reputation You're being filtered — warming or blocklist issue
SpamRelated Suspect content/sender
Quotas Mailbox full — soft, retry later
Authentication DKIM/SPF/DMARC misalignment
Throttled Slow down (4xx) — retry per backoff

Hook to react in code:

kumo.on('smtp_client_message_delivered', function(msg, response) end)

kumo.on('smtp_client_message_bounced', function(msg, response)
  local cat = response:bounce_classification()
  if cat == 'InvalidRecipient' then
    suppress(msg:recipient())
  end
end)

Sign in to keep track of what you have read.

Pulse · self-hosted sending

Own the infrastructure your pipeline depends on.

One install script on your own server. Pulse sets up the MTA, mailboxes, certificates and dashboard; you add domains and start sending.

# on a fresh Ubuntu server
$ cd pulse && sudo ./install.sh
→ docker compose up · kumomta · stalwart · caddy
→ dashboard ready on https://pulse.yourdomain.com
$

Also from us:Beat — monitoring that tells you the fixConsulting — $65/hr, no retainer