Postfix Mail Loopback Issue: Fixing “mail for domain loops back to myself” Error in Bounced Email Handling


2 views

When working with Postfix mail servers, one particularly frustrating issue occurs when bounce messages trigger a loopback error. The specific error message:

status=bounced (mail for domain loops back to myself)

This typically happens under these conditions:

  • When sending to non-existent addresses at providers like Yahoo (immediate rejection)
  • When using VERP (Variable Envelope Return Path) addresses
  • When the bounce notification tries to return to a sender address that resolves back to your own server

Let's examine the key differences between working and failing scenarios from the logs:

Successful Case (RealTSP)

Oct  6 16:46:08 milford postfix/bounce[58483]: 5027DD6E971: sender non-delivery notification: EA68FD6EAB7
Oct  6 16:46:08 milford postfix/qmgr[57929]: EA68FD6EAB7: from=<failures-xxxxx=news.t1ps@news.t1ps>, size=11600, nrcpt=1 (queue active)
Oct  6 16:46:09 milford postfix/lmtp[58484]: EA68FD6EAB7: to=<user@news.t1ps>, relay=smtp.news.t1ps[/var/imap/socket/lmtp], status=sent

Failing Case (Yahoo)

Oct  6 16:42:10 milford postfix/bounce[57756]: 33EBBD6EE87: sender non-delivery notification: A083ED6EA01
Oct  6 16:42:10 milford postfix/qmgr[57598]: A083ED6EA01: from=<failures-xxxxx=news.t1ps@news.t1ps>, size=11696, nrcpt=1 (queue active)
Oct  6 16:42:10 milford postfix/smtp[57631]: A083ED6EA01: to=<user@news.t1ps>, status=bounced (mail for news.t1ps loops back to myself)

The root cause lies in how Postfix handles VERP addresses during bounce processing. Here are the key configuration elements involved:

main.cf Settings That Matter

myhostname = smtp.news.t1ps
virtual_mailbox_domains = news.t1ps, domain2, domain3.co.uk, domain4
virtual_alias_maps = hash:/usr/local/etc/postfix_rsh/virtual
virtual_mailbox_maps = hash:/usr/local/etc/postfix_rsh/virtual_mailbox_maps

Virtual Mailbox Maps

failures@news.t1ps dummy

To fix this issue, we need to implement several configuration changes:

  1. Create a dedicated bounce handler domain
  2. Configure proper transport mapping
  3. Update the virtual mailbox maps

Implementation Steps

Step 1: Add a bounce domain to your DNS and Postfix configuration

# In /etc/postfix/main.cf
bounce_notice_recipient = postmaster@news.t1ps
bounce_service_name = defer

Step 2: Modify your transport maps

# /usr/local/etc/postfix_rsh/transport
news.t1ps     lmtp:unix:/var/imap/socket/lmtp
bounces.t1ps  local:

Step 3: Update your virtual_mailbox_maps

# /usr/local/etc/postfix_rsh/virtual_mailbox_maps
failures@news.t1ps      dummy
@bounces.t1ps           dummy

After implementing these changes, test with both scenarios:

# Test with immediate rejection (Yahoo case)
echo "Test" | mailx -s "Test Yahoo" nonexistent@yahoo.com

# Test with delayed rejection (RealTSP case)
echo "Test" | mailx -s "Test RealTSP" nonexistent@realtsp.com

For systems using VERP, add these additional settings:

# In main.cf
recipient_delimiter = +
default_verp_delimiters = +=
verp_delimiter_filter = +=

And create a dedicated VERP bounce handler:

# In master.cf
verp-bounce unix -       n       n       -       -       pipe
  flags=R user=verp argv=/usr/local/libexec/verp-bounce ${sender} ${recipient}

After all changes, run these commands to verify:

postmap /usr/local/etc/postfix_rsh/virtual_mailbox_maps
postmap /usr/local/etc/postfix_rsh/transport
postfix reload

The key is ensuring your bounce messages have a clear path that doesn't create a loopback to your primary mail domain.


When working with Postfix mail servers, you might encounter a particularly stubborn issue where bounce messages trigger the error:

Sep 30 13:38:53 postfix/smtp[62566]: DB8E6D6F9EA: to=<user@domain>, relay=none, delay=0, delays=0/0/0/0, dsn=5.4.6, status=bounced (mail for domain loops back to myself)

This occurs when:

  • A message sent to an invalid recipient gets immediately rejected by the destination server (like Yahoo's 554 error)
  • Postfix attempts to generate a bounce notification
  • The bounce message's Return-Path points back to your own domain
  • Postfix detects this as a mail loop and rejects its own notification

From your configuration files, several relevant settings stand out:

# main.cf
myhostname = smtp.news.t1ps
virtual_mailbox_domains = news.t1ps, domain2, domain3.co.uk, domain4
virtual_mailbox_maps = hash:/usr/local/etc/postfix_rsh/virtual_mailbox_maps
# virtual_mailbox_maps
failures@news.t1ps dummy

Your logs show two distinct behaviors:

Working Case (RealTSP)

Oct  6 16:46:08 milford postfix/smtp[57936]: 5027DD6E971: to=<nonexistent@milford.realtsp>, 
relay=milford.realtsp[89.187.108.21]:25, delay=0.64, dsn=5.1.1, 
status=bounced (host milford.realtsp[89.187.108.21] said: 
550 5.1.1 User unknown in virtual mailbox table)

Failing Case (Yahoo)

Oct  6 16:42:10 milford postfix/smtp[57631]: A083ED6EA01: to=<failures@news.t1ps>, 
relay=none, delay=0.01, dsn=5.4.6, status=bounced 
(mail for news.t1ps loops back to myself)

The fundamental issue stems from how different mail servers handle immediate rejections versus delayed bounces. When Yahoo immediately rejects with a 554 error during the SMTP conversation, Postfix tries to send the bounce notification to the Return-Path address (which in your VERP case points back to your domain).

Here's how to properly configure your Postfix instance to handle these cases:

# In main.cf
bounce_notice_recipient = postmaster@yourdomain.com
error_notice_recipient = postmaster@yourdomain.com
notify_classes = bounce, delay, policy, protocol, resource, software

# For VERP addresses specifically
allow_percent_hack = no

Additionally, modify your virtual mailbox maps to ensure proper delivery:

# /usr/local/etc/postfix_rsh/virtual_mailbox_maps
failures@news.t1ps   OK
bounces@news.t1ps    OK
postmaster@news.t1ps OK

For more control, create a custom bounce handler script:

#!/bin/sh
# /usr/local/bin/custom_bounce_handler

# Read the bounce message from stdin
cat > /tmp/bounce.$$

# Extract important information
FROM=$(grep '^From:' /tmp/bounce.$$ | head -1)
TO=$(grep '^To:' /tmp/bounce.$$ | head -1)
SUBJECT=$(grep '^Subject:' /tmp/bounce.$$ | head -1)

# Process the bounce
logger -t postfix/bounce "Handled bounce: $SUBJECT (From: $FROM, To: $TO)"

# Clean up
rm -f /tmp/bounce.$$
exit 0

Then configure Postfix to use it:

# In master.cf
bounce    unix  -       -       n       -       0       bounce
  -o bounce_service_name=custom_bounce

custom_bounce unix -    n       n       -       -       pipe
  flags=R user=nobody argv=/usr/local/bin/custom_bounce_handler

After making changes, test with:

postmap /usr/local/etc/postfix_rsh/virtual_mailbox_maps
postfix reload

Send test messages to both valid and invalid addresses to verify proper bounce handling.

  • Ensure all bounce-related addresses exist in virtual_mailbox_maps
  • Verify your mydestination and virtual_mailbox_domains settings don't overlap
  • Consider using a separate subdomain for bounces (e.g., bounces.yourdomain.com)
  • Monitor logs closely after changes