How to delete all MAILER-DAEMON emails from your Postfix queue, when it matches a sender or recipient email address condition. When a large scale spam run was sent through your mail servers, you need to clean up and remove those spam messages. Doing so guarantees normal, valid email messages being sent quickly, and the spam messages never leave your queue. In Postfix, there are various similar commands to delete messages from the Postfix mail queue. Based on the Message-ID and/or email address…

Postfix logo

Postfix logo

How to delete all emails from a Postfix queue when it matches an address condition

Here is how you can delete mail from the mail queue in Postfix, based on a condition. For example all MAILER-DAEMON emails or spam, by sender or recipient address.

I use this regularly to remove spam from my Postfix SMTP server mail queue.

If you want to delete emails from your Postfix queue based on a sender address – spammer@example.com for example – you need to feed the mailq output to awk. The result is fed to postsuper for deletion:

mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $7 == "spammer@example.com" ) print $1 }
' | tr -d '*!' | postsuper -d -
mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $7 ~ "@example.com" ) print $1 }
' | tr -d '*!' | postsuper -d -

Here, $7 represents the sender address (7th awk field), either full (spammer@example.com) or matched by regular expression (~ @example.com).

This may interest you:   SMTP over Hidden Services with postfix

Do you want to delete message sent to a particular address? Use $8 or $9 as they represent recipient addresses:

mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $8 == "spammer@example.com" ) print $1 }
' | tr -d '*!' | postsuper -d -
mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $8 == "spammer@example.com" && $9 == "" ) print $1 }
' | tr -d '*!' | postsuper -d -
mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $8 == "spammer@example.com" || $8 == "spammer2@example2.com" ) print $1 }
' | tr -d '*!' | postsuper -d -

and so on.

But what if those spam mails already left your system? And can’t be delivered? Then you’re stuck with hundreds of thousands MAILER-DAEMON messages. Of course you can delete all those mails from your Postfix queue: just use MAILER-DAEMON as sender address in the above scripts.

But doing so, you probably also delete other, possibly valid MAILER-DAEMON mails informing you about undeliverable emails. Therefore you need to build in a condition.

The following shell script scans through the Postfix mail queue – using the mailq command – looking for messages sent by MAILER-DAEMON, or any other email address you provide as argument. Of those message-id’s it scans to see if the recipient condition is matched.

This may interest you:   Sysadmins of the North goes global!

Those messages are then deleted from the queue by executing postsuper -d -.

The following example script takes the recipient email address as input, and deletes all mails where MAILER-DAEMON is the sender:

#!/bin/bash
EMAILADDY=$1

if [ -z "$EMAILADDY" ]
then
  echo "Usage: $0 <email adres>"
  exit
fi

echo "Delete all emails addressed to $EMAILADDY, and sent by MAILER-DAEMON, from our Postfix queue."

mailq | tail -n +2 | grep -v '^ *(' | awk -v "address=$EMAILADDY" 'BEGIN { RS = "" }
  { 
    # example conditions:
    #   if ( $7 == "MAILER-DAEMON && $8 == address && $9 == "" )
    #   if ( $7 == "MAILER-DAEMON && $8 == "" && $9 == address )
    #   if ( $7 == "MAILER-DAEMON && $8 == address || $9 == address )
    if ( $7 == "MAILER-DAEMON && $8 == address )
      print $1 
  }
' | tr -d '*!' | postsuper -d -

Call your script on the command line providing a recipient email address:

sh ./delete-mail-from-queue.sh spammer@example.com

Postfix, delete all mails from the queue queue sent by spammer@example.com:

#!/bin/bash
EMAILADDY=$1

if [ -z "$EMAILADDY" ]
then
  echo "Usage: $0 <email address>"
  exit
fi

echo "Delete all emails addressed to $EMAILADDY from our Postfix queue."

mailq | tail -n +2 | grep -v '^ *(' | awk -v "address=$EMAILADDY" 'BEGIN { RS = "" }
  { 
    # example conditions:
    #   if ( $8 == address && $9 == "" )
    #   if ( $8 == address || $9 == address )
    if ( $8 == address )
      print $1 
  }
' | tr -d '*!' | postsuper -d -

Call your script on the command line providing an email address:

sh ./delete-mail-from-queue.sh spammer@example.com

To use a regular expression in Awk, suppose you want to match all emails from various @example.com addresses, change the line if ($8 == address) to:

# the sender is the 7th Awk field, thus $7
if ($7 ~ address)

and provide only example.com as a parameter:


sh ./delete-mail-from-queue.sh example.com

Again, use $8 and/or $9 to match recipients, assuming MAILER-DAEMON is the sender / $7.

Note: Always be careful when messing with mail queues, and especially regular expressions. Another easy usage example is to release Postfix hold queue.