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
mailqshows 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.Examine the queue and identify patterns:
- 2.```bash
- 3.# Postfix
- 4.mailq | head -50
- 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.Check specific deferred message details:
- 2.```bash
- 3.# View full details of a queued message
- 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.Test connectivity to the remote mail server:
- 2.```bash
- 3.# Look up MX records
- 4.dig +short mx recipient.com
- 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.Flush the queue to retry delivery:
- 2.```bash
- 3.# Retry all deferred messages
- 4.postqueue -f
# Retry only messages for a specific domain postqueue -s recipient.com
# Force immediate delivery attempt postsuper -r ABC123DEF0 postqueue -f ```
- 1.Remove permanently undeliverable messages:
- 2.```bash
- 3.# Delete a specific message
- 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.Configure relay host for reliable delivery:
- 2.```bash
- 3.# /etc/postfix/main.cf
- 4.relayhost = [smtp.yourprovider.com]:587
- 5.smtp_sasl_auth_enable = yes
- 6.smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
- 7.smtp_sasl_security_options = noanonymous
- 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.Monitor queue size and set alerts:
- 2.```bash
- 3.# Add to crontab for monitoring
- 4.# Check every 5 minutes
- 5.*/5 * * * * /usr/sbin/postqueue -p | tail -1 | awk '{print $7}' | \
- 6.xargs -I{} bash -c 'if [ {} -gt 100 ]; then echo "ALERT: {} messages in queue" | mail -s "Mail Queue Alert" admin@example.com; fi'
- 7.
`
Prevention
- Use a reliable SMTP relay service (SendGrid, SES, Mailgun) for outbound mail
- Configure
maximal_queue_lifetime = 3dto expire old messages - Set
bounce_queue_lifetime = 1dto send bounces promptly - Monitor queue size with automated alerts
- Keep your IP off blacklists by following email best practices
- Use
smtp_destination_rate_delayto avoid overwhelming remote servers