Bounce processing, when SMTP server doesn’t return bounces properly

What bounce processing is

When you send an email, it’s possible that it’s returned to you because of technical problems or mistakes made when writing the email.

One of these mistakes may be that the recipient’s email address is wrong.

CRM sending mass emails

Many CRMs, Customer Relationship Management system, have the capability of sending mass mailing.

They can send the same newsletter to hundreds or thousands of recipients.

CRM processing bounces

If an email is returned because of any problem, the CRM will process it.

If an email is returned because the email address of the recipient is wrong, the CRM will put the contact on hold.

CiviCRM and bounce processing

I’m using CiviCRM as CRM. When I send a mailing to many contacts, CiviCRM sets the “Return-Path” header in the email to be something like: return+b.19.5.9c232c48e0ba219a (...)

When an email is returned because of errors, it should be sent to

The additional part b.19.5.9c232c48e0ba219a in the email address will tell CiviCRM which mailing and contact the original email was about.

By using this information, CiviCRM will put the contact on hold, sometimes immediately, sometimes after a few failures occurred.

SMTP server not returning bounces correctly

It happens that the SMTP server I’m using, and many others, don’t process bounces properly.

They should send the failure message to return+b.19.5.9c232c48e0ba219a (...) and the email should show up in the mailbox.

CiviCRM should have nothing else to do than check the recipient, return+b.19.5.9c232c48e0ba219a (...), and do its processing.

Instead, the SMTP server sends the email back to where it was from,

If CiviCRM checks the recipient, it doesn’t find the information it needs to process the bounce.

Scanning the entire email’s body

The solution is to scan the entire body of the returned email because somewhere there will be written that address CiviCRM needs.

CiviCRM uses a regular expression like:


  1. '/Return-Path: ' . preg_quote($dao->localpart) . '(b)' . $twoDigitString . '([0-9a-f]{16})@' . preg_quote($dao->domain) . '/'


Let’s say that the returned email contains the headers of the original email:


  1. Return-Path:return (...)

  2. Received:from ( []) by

  3. with SMTPS id 1444752405240749.4338448238343; Tue, 13 Oct 2015 09:06:45 -0700 (PDT)

  4. Date:Tue, 13 Oct 2015 17:06:44 +0100


The regular expression above will find the line:


  1. Return-Path:return+b.19.5.9c232c48e0ba219a (...)


and CiviCRM will process the bounce correctly.

Problem solved?

Yes, you got it, the regular expression above won’t find the line with the return path because it looks for a space that is missing.

It should be:


  1. '/Return-Path:' . preg_quote($dao->localpart) . '(b)' . $twoDigitString . '([0-9a-f]{16})@' . preg_quote($dao->domain) . '/'


(full article: Bounce processing, when SMTP server doesn’t return bounces properly)