postsleuth
! smtpdfrom the internet pickupsendmail, apps cleanup incoming active smtp local mailboxes gmail.com421 4.7.28 rate limited outlook.comS3150 block list fastmail.comgood service hold deferred 205 waiting bounce returned to sender

postsleuth · Postfix delivery network

Why isn't Postfix delivering?

One read-only command, or one MCP call from your agent, tells you which destinations are stuck, since when, for what reason, and which DNS record is to blame.

  • delivery
  • deferred loop
  • hold
  • bounce

Line status, from your own queue

postsleuth doctor reads postqueue -j, the mail log and DNS, groups every delay reason, classifies it and says what to do next. Here it is against a server that has been sending a little too fast.

  1. gmail.comSevere delaysrate_limit · 150 recipients · 421-4.7.28 Gmail has detected an unusual rate…Stop flushing. Lower smtp_destination_concurrency_limit, add a rate delay, test one connection after 10 minutes.
  2. outlook.com, hotmail.comPart suspendedblocklist · 34 recipients · 550 5.7.1 … on our block list (S3150)Your IP is listed. Look it up in Microsoft SNDS, fix the cause, request delisting.
  3. oldcorp.exampleMinor delaystimeout · 14 recipients · connect to mx.oldcorp.example:25: Connection timed outTest nc -vz mx 25. If every destination times out, your provider blocks port 25: use a relayhost.
  4. acme-typo.exampleCloseddns · 4 recipients · Host or domain name not foundThe domain has no MX or A record. Fix the address.
  5. smallbiz.exampleGood service soongreylisting · 3 recipientsNormal. Postfix retries on its own.
  6. example.com DNS1 warningSPF ok · DKIM mail 2048-bit · DMARC p=none, no rua= · PTR forward-confirmedAdd rua= so you get aggregate reports.

Connections with other networks

Some closures happen on someone else's line. When Gmail, Outlook.com or Yahoo refuses you, the reply carries their code, and each of them has its own way back. postsleuth playbook recognises the provider and the code, says whether Postfix's retries can work, and gives the steps in order, with the provider's own pages. 18 playbooks; doctor shows the ones that match.

Connections

Also: Gmail 5.7.26 DMARC, PTR, TLS · Microsoft 365 banned IP, 5.7.511, 4.7.650 · Yahoo [TSS09], [BL21]… all 18

gmail-4.7.28

Gmail is rate limiting you

temporary · Postfix retries

  1. Stop. Send nothing to Gmail for 10 minutes, and don't flush the queue.
  2. Read which quota you hit: IP, netblock, DKIM, SPF or URL domain.
  3. Reopen on one connection: a gmail transport with gmail_destination_concurrency_limit = 1.
  4. Accepted? Add one connection at a time. Deferred again? Wait another 10 minutes.
  5. Find the spike: a bulk send, a cold IP, a compromised account.
  6. Keep the spam rate in Postmaster Tools under 0.10%, never 0.30%.

Official: Google sender guidelines · Postmaster Tools

microsoft-s3150

Outlook.com has your network on its block list

permanent · retrying won't help

  1. Fix the cause first: a compromised account, a bad list, SPF/DKIM/DMARC/PTR gaps.
  2. Sign in to SNDS and check your IP's status and complaint data.
  3. Join JMRP to see who marks you as junk, and stop mailing them.
  4. Ask for delisting on the Outlook.com sender support form, with the IP and the bounce line.

Official: Outlook.com Postmaster · SNDS · sender support

yahoo-deferred

Yahoo is deferring your mail

temporary · Postfix retries

  1. Let Postfix back off. No flushing, no moving the mail to other IPs.
  2. Cap Yahoo, AOL and the rest together: a yahoo transport with a process limit of 2.
  3. Find what changed: volume, a new IP, a campaign people complain about.
  4. Enrol your DKIM domain in Yahoo's Complaint Feedback Loop.
  5. Still deferred after a long while? Send Yahoo a sender support request.

Official: Yahoo error codes · Complaint Feedback Loop

Seven stops, one line

  1. queuepostsleuth queue

    Counts per queue, top domains, every delay reason grouped and classified into 17 causes with a hint.

  2. shapepostsleuth shape

    The qshape view: which destination is backing up, and since when, in age buckets.

  3. logpostsleuth log --since 24h

    Sent, deferred, bounced, expired, rejected per domain. Bounce causes. Domains still failing. Trace any message.

  4. trendpostsleuth trend

    Deferral rate per destination over time buckets. Improving, worsening, or flat — is Gmail getting better?

  5. dnspostsleuth dns

    MX, SPF (10-lookup limit, is your IP allowed), DKIM keys, DMARC, PTR with forward confirmation.

  6. playbookpostsleuth playbook

    Gmail 4.7.28, Outlook S3150, Yahoo [TSS04]: the provider's own way back, step by step.

  7. doctorpostsleuth doctor

    All of it in one report with next steps. Exit code 1 when something is wrong.

Who is waiting on the platform

The qshape matrix of the deferred queue: rows are destination domains, columns are minutes in the queue. gmail.com piled up over the last five hours. oldcorp.example has been failing for two days.

postsleuth shape deferred · --by sender finds the account that is spamming.

Change here for your AI agent

postsleuth mcp is a Model Context Protocol server on stdio. Ask Claude, Cursor or any MCP client "why is mail to Gmail stuck?" and it calls the same tools you would run by hand. Run it on the mail host, through SSH, or next to a Postfix container.

  1. postfix_doctor
  2. postfix_queue_summary
  3. postfix_queue_list
  4. postfix_queue_shape
  5. postfix_log_stats
  6. postfix_log_trend
  7. postfix_log_trace
  8. postfix_provider_playbook
  9. mail_dns_check
  10. postfix_config
// on the mail server
{"mcpServers": {"postsleuth": {
  "command": "postsleuth", "args": ["mcp"]}}}
// from your laptop, over SSH
{"mcpServers": {"postsleuth": {
  "command": "ssh", "args": ["mx1", "postsleuth", "mcp"]}}}
// Postfix in Docker (docker-mailserver, mailcow)
{"mcpServers": {"postsleuth": {"command": "postsleuth",
  "args": ["mcp", "--wrap", "docker exec -i mailserver"]}}}

The siding is locked

Every tool reads. Flush, requeue, hold, release and delete live on a siding that stays locked unless you start postsleuth with --allow-mutations. Your agent cannot unlock it. Even when it is open, each change over MCP needs confirm=true, takes explicit queue IDs, and ALL is refused.

read-only tools flush · requeue · hold · release · delete

Board here

$ go install github.com/Blackman99/postsleuth/cmd/postsleuth@latest
$ postsleuth doctor

Or download one static binary for Linux, macOS or Windows from Releases. Needs read access to the mail log (the adm group on Debian/Ubuntu). postqueue -j works as any user. CI tests every build against a real Postfix in Docker.