How to Permanently Remove Stuck Messages from Sendmail Queue and Prevent Respawn


1 views

When working with sendmail during application testing, developers often encounter the frustrating behavior of queued messages that keep reappearing even after manual deletion. The standard location for these messages in Ubuntu is /var/spool/mqueue/, but simply removing files from this directory only provides temporary relief.

The messages regenerate because of two key processes:

Jun  2 17:40:01 sajo-laptop CRON[9523]: (smmsp) CMD (test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp)

This cron job triggers queue processing, while sendmail's internal database maintains record of pending messages.

To permanently eliminate queued messages:

  1. Stop sendmail service:
    sudo service sendmail stop
    
  2. Clear the queue directory:
    sudo rm -f /var/spool/mqueue/*
    
  3. Remove the persistent queue database:
    sudo rm -f /var/spool/mqueue/*.qf
    
  4. Prevent future queue processing:
    sudo chattr +i /var/spool/mqueue
    

For development environments, consider these alternatives:

Option 1: Configure sendmail to discard messages:

FEATURE(nullclient', localhost')dnl
define(confDELIVERY_MODE', q')dnl

Option 2: Use Python's debugging SMTP server:

python -m smtpd -n -c DebuggingServer localhost:25

For long-term queue control:

  • Set shorter retry intervals in sendmail.mc:
    define(confQUEUE_LA', 5')dnl
    define(confMIN_QUEUE_AGE', 1h')dnl
    
  • Install mailq management tools:
    sudo apt-get install postfix
    sudo postsuper -d ALL deferred
    

When testing email functionality in applications, developers often encounter situations where test messages get stuck in the sendmail queue. These messages typically target non-existent addresses or domains that reject connections, causing sendmail to continuously retry delivery.

Sendmail maintains its queue in /var/spool/mqueue/ (or /var/spool/clientmqueue/ for MSP). The queue files follow specific naming conventions:

df* - message data
qf* - queue control file
xf* - temporary files

Simply deleting files from the queue directory isn't sufficient because:

  1. Sendmail may have open file handles
  2. The mailq database needs updating
  3. Cron jobs may rebuild the queue

Here's the correct way to purge messages:

# Stop sendmail first
sudo service sendmail stop

# Remove queue files
sudo find /var/spool/mqueue/ -type f -exec rm -f {} \;

# Clear the mailq database
sudo rm -f /var/spool/mqueue/*.lock /var/spool/mqueue/*.temp

# Restart sendmail
sudo service sendmail start

To stop cron from repopulating the queue:

# Disable the sendmail queue runner
sudo chmod -x /etc/cron.d/sendmail

Or edit the cron job directly:

sudo nano /etc/cron.d/sendmail
# Comment out the line:
# */30 * * * * smmsp test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp

For development environments, configure sendmail to discard messages instead of attempting delivery:

# Edit sendmail configuration
sudo nano /etc/mail/sendmail.mc

# Add these lines:
define(confDELIVERY_MODE', q')dnl
define(confQUEUE_LA', 0')dnl
define(confTO_QUEUEWARN', 0')dnl
define(confTO_QUEUERETURN', 0')dnl

# Rebuild the configuration
sudo make -C /etc/mail
sudo service sendmail restart

For pure testing environments, consider replacing sendmail with nullmailer:

sudo apt-get install nullmailer
sudo nano /etc/nullmailer/remotes
# Add this line:
127.0.0.1 smtp --port=25 --starttls --user= --pass=

Here's a handy bash script to monitor and clean the queue:

#!/bin/bash

QUEUE_DIR="/var/spool/mqueue"
MAX_AGE="14400" # 4 hours in seconds

# List current queue
echo "Current queue status:"
mailq

# Find and remove old messages
find "$QUEUE_DIR" -type f -mmin +$((MAX_AGE/60)) -exec rm -f {} \;

# Optional: Restart sendmail
# service sendmail restart