« YAASI: Yet Another Anti-Spam Idea | Main | More Compiler Complaints: Sparc Edition »

I Hate Procmail

Its error handling is CRAP.

I am coming to this realization because I recently lost a BUNCH of messages because of a bad delivery path (I told procmail to pipe messages to a non-existent executable). So what did procmail do? According to its log:

/bin/sh: /tmp/dovecot11/libexec/dovecot/deliver: No such file or directory
procmail: Error while writing to "/tmp/dovecot11/libexec/dovecot/deliver"

Well, sure, that’s to be expected, right? So what happened to the email? VANISHED. Into the bloody ether.

Of course, determining that the message vanished is trickier than just saying “hey, it’s not in my mailbox.” Oh no, there’s a “feature”, called ORGMAIL. What is this? According to the procmailrc documentation (*that* collection of wisdom):

ORGMAIL     Usually the system  mailbox  (ORiGinal  MAIL‐
            box).   If,  for  some  obscure  reason (like
            ‘filesystem full’)  the  mail  could  not  be
            delivered, then this mailbox will be the last
            resort.  If procmail fails to save  the  mail
            in  here  (deep,  deep  trouble :-), then the
            mail will bounce back to the sender.

And so where is THAT? Why, /var/mail/$LOGNAME of course, where else? And if LOGNAME isn’t set for some reason? Or what if ORGMAIL is unset? Oh, well… nuts to you! Procmail will use $SENDMAIL to BOUNCE THE EMAIL rather than just try again later. That’s what they mean by “deep, deep trouble.” Notice the smiley face? Here’s why the manual has a smiley-face in it: to mock your pain.

But here’s the real crux of it: procmail doesn’t see delivery errors as FATAL. If one delivery instruction fails, it’ll just keep going through the procmailrc, looking for anything else that might match. In other words, the logic of your procmailrc has to take into account the fact that sometimes mail delivery can fail. If you fail to do this, your mail CAN end up in RANDOM LOCATIONS, depending on how messages that were supposed to match earlier rules fare against later rules.

If you want “first failure bail” behavior (which makes the most sense, in my mind), you have to add an extra rule after EVERY delivery instruction. For example:

:0 H
* ^From: .*fred@there\.com

:0 e # handle failure
    EXITCODE=75 # set a non-zero exit code
    HOST # This causes procmail to stop, obviously

You agree that HOST means “stop processing and exit”, right? Obviously. That’s procmail for you. Note that that second clause has gotta go after EVERY delivery instruction. I hope you enjoy copy-and-paste.

Another way to handle errors, since successful delivery does stop procmail, is to add something like that to the end of your procmailrc, like so:

:0 # catch-all default delivery

 # If we get this far, there must have been an error

Of course, you could also send the mail to /dev/null at that point, but unsetting the HOST variable (which is what listing it does) does the same thing faster. Intuitive, right? Here’s my smiley-face:



TrackBack URL for this entry:

Comments (1)

Hehe :)

I run procmail from .qmail-default. Actually it's a preprocmail script. Procmail and maildrop are not allowed to deliver mail, unless it's a rule.
So I make sure that if either don't deliver, the script exits correctly so vdelivermail still delivers.

Heres my preprocmail script:
VPOPMAIL=`echo ~vpopmail`
DOMDIR=`/usr/local/vpopmail/bin/vuserinfo -d $EXT@$HOST`
if [ -r $DOMDIR/.skipfilter ]
cat > /dev/null
exit 0

if [ -r $DOMDIR/.procmailrc ]
# echo "Run Thus"
#env -i DOM=$HOST USERNAME=$EXT DEFAULT=$DEFAULT /usr/local/bin/procmail -p -m $DOMDIR/.procmailrc
`/usr/local/bin/procmail -p -m $DOMDIR/.procmailrc`
cat > /dev/null
if [ $EXITCODE -ne 0 ]; then
exit 0
#Exited with 0, delivered, so set 99 to stop vdelivermail
exit 99
cat > /dev/null
exit 0

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


This page contains a single entry from the blog posted on June 27, 2008 10:33 AM.

The previous post in this blog was YAASI: Yet Another Anti-Spam Idea.

The next post in this blog is More Compiler Complaints: Sparc Edition.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.34