Introduction

When an email server cannot deliver messages to their destination, they accumulate in the mail queue in a deferred status. This can be caused by the remote server being unreachable, DNS resolution failures, relay authentication issues, or the remote server temporarily rejecting messages. A large deferred queue leads to delayed email delivery, increased disk usage, and potential bounce storms when messages eventually expire.

Symptoms

  • mailq shows hundreds or thousands of deferred messages:
  • `
  • -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
  • ABC123DEF0 4521 Mon Apr 7 10:15:23 sender@example.com
  • (connect to mx.recipient.com[1.2.3.4]:25: Connection timed out)
  • recipient@recipient.com
  • DEF456GHI1 3892 Mon Apr 7 09:42:11 sender@example.com
  • (Host or domain name not found. Name service error)
  • user@nonexistent-domain.com
  • `
  • Disk usage growing:
  • ```bash
  • du -sh /var/spool/postfix/deferred
  • 2.1G /var/spool/postfix/deferred
  • `
  • Mail log shows repeated delivery attempts:
  • `
  • postfix/smtp[12345]: connect to mx.recipient.com[1.2.3.4]:25: Connection timed out
  • postfix/smtp[12345]: ABC123DEF0: to=<recipient@recipient.com>, relay=none, delay=3600, delays=3540/60/0/0, status=deferred
  • `

Common Causes

  • Remote mail server is down or blocking your IP
  • DNS resolver cannot find MX records for destination domain
  • SMTP relay host credentials expired or changed
  • Outbound port 25 blocked by ISP or cloud provider
  • Greylisting at the receiving server causing repeated deferrals
  • SPF/DKIM failures causing recipient server to soft-reject

Step-by-Step Fix

  1. 1.Examine the queue and identify patterns:
  2. 2.```bash
  3. 3.# Postfix
  4. 4.mailq | head -50
  5. 5.postqueue -p

# Count deferred messages postqueue -p | tail -1 # Output: -- 1234 Kbytes in 567 Requests.

# Group by error type mailq | grep -oP '\(.*?\)' | sort | uniq -c | sort -rn ```

  1. 1.Check specific deferred message details:
  2. 2.```bash
  3. 3.# View full details of a queued message
  4. 4.postcat -q ABC123DEF0

# Check why a message is deferred postconf -h queue_directory # Default: /var/spool/postfix cat /var/spool/postfix/deferred/ABC123DEF0 | strings | head -30 ```

  1. 1.Test connectivity to the remote mail server:
  2. 2.```bash
  3. 3.# Look up MX records
  4. 4.dig +short mx recipient.com
  5. 5.# Output: 10 mx.recipient.com.

# Test SMTP connection telnet mx.recipient.com 25 # Or: openssl s_client -connect mx.recipient.com:465 -quiet

# Check if your IP is blacklisted curl https://api.hetrixtools.com/v2/blacklist/YOUR_API_KEY/YOUR_IP ```

  1. 1.Flush the queue to retry delivery:
  2. 2.```bash
  3. 3.# Retry all deferred messages
  4. 4.postqueue -f

# Retry only messages for a specific domain postqueue -s recipient.com

# Force immediate delivery attempt postsuper -r ABC123DEF0 postqueue -f ```

  1. 1.Remove permanently undeliverable messages:
  2. 2.```bash
  3. 3.# Delete a specific message
  4. 4.postsuper -d ABC123DEF0

# Delete ALL deferred messages (use with caution) postsuper -d ALL deferred

# Delete messages older than 5 days from deferred queue find /var/spool/postfix/deferred -type f -mtime +5 -exec rm {} \; ```

  1. 1.Configure relay host for reliable delivery:
  2. 2.```bash
  3. 3.# /etc/postfix/main.cf
  4. 4.relayhost = [smtp.yourprovider.com]:587
  5. 5.smtp_sasl_auth_enable = yes
  6. 6.smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
  7. 7.smtp_sasl_security_options = noanonymous
  8. 8.smtp_tls_security_level = encrypt

# /etc/postfix/sasl_passwd [smtp.yourprovider.com]:587 username:password

# Apply changes postmap /etc/postfix/sasl_passwd chmod 600 /etc/postfix/sasl_passwd systemctl restart postfix ```

  1. 1.Monitor queue size and set alerts:
  2. 2.```bash
  3. 3.# Add to crontab for monitoring
  4. 4.# Check every 5 minutes
  5. 5.*/5 * * * * /usr/sbin/postqueue -p | tail -1 | awk '{print $7}' | \
  6. 6.xargs -I{} bash -c 'if [ {} -gt 100 ]; then echo "ALERT: {} messages in queue" | mail -s "Mail Queue Alert" admin@example.com; fi'
  7. 7.`

Prevention

  • Use a reliable SMTP relay service (SendGrid, SES, Mailgun) for outbound mail
  • Configure maximal_queue_lifetime = 3d to expire old messages
  • Set bounce_queue_lifetime = 1d to send bounces promptly
  • Monitor queue size with automated alerts
  • Keep your IP off blacklists by following email best practices
  • Use smtp_destination_rate_delay to avoid overwhelming remote servers