How to Verify Email Delivery Status in Postfix Mail Server Logs


6 views

When troubleshooting email delivery issues with Postfix, the key information you need to verify is whether your mail server successfully delivered the message to the recipient's mail server. The standard Postfix logs show queue activity but don't always clearly indicate final delivery status.

Here are the critical log patterns to look for in /var/log/mail.log or your system's equivalent:

# Successful delivery:
postfix/smtp[12345]: 1A2B3C4D5E: to=<recipient@example.com>, relay=mail.example.com[1.2.3.4]:25, delay=1.2, delays=0.1/0/0.5/0.6, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 12345ABCDEF)

# Failed delivery:
postfix/smtp[12345]: 1A2B3C4D5E: to=<recipient@example.com>, relay=mail.example.com[1.2.3.4]:25, delay=1.5, delays=0.1/0/0.5/0.9, dsn=5.0.0, status=bounced (host mail.example.com[1.2.3.4] said: 550 5.0.0 No such user)

To get more detailed delivery information, add these settings to your main.cf:

# Enable verbose logging for SMTP transactions
debug_peer_level = 2
debug_peer_list = example.com

# Log the complete message delivery status
bounce_notice_recipient = postmaster
delay_warning_time = 4h

The postsuper command helps examine the mail queue:

# List all messages in the queue
postsuper -l

# Check specific message details
postcat -q 1A2B3C4D5E

Here's a bash script to parse Postfix logs for delivery confirmation:

#!/bin/bash

LOG_FILE="/var/log/mail.log"
MESSAGE_ID="$1"

if [[ -z "$MESSAGE_ID" ]]; then
    echo "Usage: $0 <message-id>"
    exit 1
fi

grep "$MESSAGE_ID" "$LOG_FILE" | \
    grep -E 'status=(sent|bounced|deferred)' | \
    awk -F': ' '{print $2}'

exit 0

For comprehensive monitoring, consider these approaches:

  • Set up mailgraph for visual log analysis
  • Use pflogsumm for daily delivery reports
  • Implement sentry for real-time delivery alerts

When troubleshooting email delivery issues with Postfix, the default logging often leaves administrators wanting more detailed information. The typical queue manager entries like:

Sep 14 06:27:10 mailhost postfix/qmgr[21603]: 14B40C65A1: from=, size=1372, nrcpt=1 (queue active)

only show that a message entered the queue, not whether it was successfully delivered to the recipient's mail server.

To get comprehensive delivery information, you need to configure Postfix to log SMTP transactions. Add these parameters to your main.cf:

# Enable detailed logging for SMTP transactions
debug_peer_level = 2
debug_peer_list = example.com  # Optional: limit verbose logging to specific domains

# Log the complete delivery process
smtpd_verbose = yes

With these settings, you'll see detailed delivery attempts like:

Sep 14 06:27:12 mailhost postfix/smtp[12345]: 14B40C65A1: to=, relay=mx.example.com[192.0.2.1]:25, delay=2.4, delays=0.1/0.2/1.2/0.9, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 1A2B3C4D)

Key elements to check:

  • status=sent: Message was accepted by recipient server
  • dsn=2.0.0: Delivery Status Notification code (2xx = success)
  • queued as: The remote server's queue ID for tracking

Use postqueue and postcat commands to examine the queue:

# List all queued messages
postqueue -p

# View message details by queue ID
postcat -q 14B40C65A1

For critical messages, consider these additional methods:

# 1. Enable delivery receipts in main.cf
delay_notice_recipient = postmaster@yourdomain.com

# 2. Use mailq for queue inspection
mailq

# 3. Check delivery attempts with grep
grep "14B40C65A1" /var/log/maillog*

When messages are rejected, you'll see entries like:

postfix/smtp[12345]: 14B40C65A1: to=, relay=none, delay=3600, status=deferred (connect to example.com[192.0.2.1]: Connection timed out)

Common status codes:

  • 4xx: Temporary failure (retry will be attempted)
  • 5xx: Permanent failure (message will bounce)

Create a monitoring script to parse logs:

#!/bin/bash
# Check recent deliveries for a specific recipient
RECIPIENT="user@example.com"
LOG="/var/log/maillog"
DAYS=1

zgrep -h "to=<$RECIPIENT>" $LOG* --date=@d -$DAYS | grep "status="