Skip to content

Postfix local mail forwarding loop

OK, somebody did something foolish and forwarded mail to themselves.

fred@imap $ cat ~/.forward
fred@imap $

So now postfix sees a mail forwarding loop and your deferred queue is full of undelivered mail:

Dec 20 18:19:06 imap postfix/local[19833]: AE23C7F38: to=<>, orig_to=<>, relay=local, delay=27688, delays=27687/0.61/0/0.01, dsn=4.4.6, status=SOFTBOUNCE (mail forwarding loop for

So you fix your user’s .forward file and do postqueue -f to flush it and … it tries to redeliver all the loop mail and complains that there’s a mail loop.

Hrm. So you look all over online, and find that qmgr can be run with a -v flag in and you reload postifx, and try to flush the queue again, and you see all sorts of detailed debugging like:

local recip exten deliver exp_from

and then just a message that says there’s a loop.

You read local(8) and discern that the problem may be a Delivered-To: header and when you search on that online you see several suggestions to add lines like:

> /^Delivered-To: .* IGNORE

So you wire that up and flush the queue and find out that … you have a mail forwarding loop. You may then futz with canonical rewrites and all kinds of other thrashing but all of that won’t work.

So, here’s what’s going on:

  • You do have a Deliver-To header problem
  • This is noticed by the local delivery agent
  • Your queue file isn’t going to be processed by the rewrite agent, the header checks, or anything – those phases are all past.
  • There’s no way to tell local(8) to ignore the Delivered-To header
  • You’re basically SOL as far as elegant solutions

“Unacceptable!” you shout. “And who ever heard of elegant?”

So we’re going to do something so horrible and dirty that the ghost of Wietse Venema will haunt you at some point in the distant future if you’re unlucky enough to outlive him. Here goes:

# systemctl stop postfix
# cd /var/spool/postfix/deferred
# perl -p -i.bak -e 's/Delivered-To/Delivered-Fo/' */*
# find ./ -name \*.bak -exec mv {} /tmp \;
# systemctl start postfix

Yes, we’re using perl as a binary version of sed. We’re using its backup function just so it preserves file ownership and modes. We’re using find to get rid of the pristine queue files. We can’t even properly Change To to Foo because you don’t add bytes to a binary file. And we’re obviously directly editing the postfix queue and munging headers in a binary file behind postfix’s back and nobody should ever do that.

And when you check all your mails just got delivered.