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="