Module 12 · Lesson 26 of 26

Diagnostic flow when delivery breaks

Part of Mailcow: Self-Hosted Mail Server Mastery — Scaling, Multi-Server & Troubleshooting Playbook.

When mail stops flowing, walk this checklist in order. Don't restart things first — read logs first.

1. Where is it stuck?

docker compose exec postfix-mailcow postqueue -p | tail -50

Queue empty? Look outbound. Queue piling up? Inbound or remote refusal.

2. What does the bounce say?

docker compose logs --tail=200 postfix-mailcow | grep "status="
  • bounced → remote rejected, read the diagnostic.
  • deferred → temporary, will retry.
  • sent → delivered, check Rspamd/Dovecot.

3. Is Rspamd rejecting?

docker compose logs --tail=200 rspamd-mailcow

Look for action=reject with the matching message-id.

4. Authentication issue? Send to check-auth@verifier.port25.com and read the full report.

5. Listed somewhere? Use MailVitals' blacklist checker for the IP and HELO hostname.

Common root causes (ranked by frequency):

  1. Outbound IP on a DNSBL (Spamhaus, UCEPROTECT).
  2. Reverse DNS broken after VPS reboot.
  3. Let's Encrypt cert expired (ACME container stuck).
  4. Disk full on vmail volume.
  5. mailcow.conf mismatch after manual edit.

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