I have a need for everyone in my organization to send emails to everyone else in the group.
As there are hundreds of members, and the membership changes often, it is not practical to use the traditional CPanel email forwarding method. So I thought I would pipe the email to a php script, get all the members’ email addresses from the database (checking to make sure the original sender was also in the database) and send on the email to all members using PHPMailer.
I parsed the header in the PHP script to get the From, Subject (adding these of course to PHPMailer), Content-Type, and boundary. Then I collected the actual email message in a variable $message including the lines that say (in this case)
“This is a multi-part message in MIME format.
--------------3D4FAACFC2C069EFCDAE6DC6, etc. (This is of course in text format.)
Just before the PHPMailer Send command, I included:
$mail -> IsHTML(false);
// (I also tried not including this command at all – no change)
$mail->Body =$message;
$mail->addCustomHeader("Content-Type", $content_type . " boundary=" . $boundary);
$content_type and $boundary are the variables I parsed from the original header
As this is still in development, I sent the email to my address only. It was received and displayed properly (both the plain and html as usual), but was marked as Spam – the received Header had the Subject already marked as Spam so I assume PHPMailer did it.
I noticed on the received Header that my custom header appeared correctly:
Content-Type: multipart/alternative; boundary="------------3D4FAACFC2C069EFCDAE6DC6"
The received header also had another Content-Type: text/plain; charset=iso-8859-1 after the above which I assume PHPMailer added. Maybe the two Content-Types is what triggered the Spam tag. I then tried adding $mail->header_remove ('Content-Type'); after the Body call and before addCustomHeader, but the additional Content-Type: text/plain; charset=iso-8859-1 was still in the received header and it was still marked as Spam.
I am using PHPMailer version 5.2.22, and using
$mail->IsSMTP();
, $mail->SMTPAuth = true;
$mail->SMTPSecure = 'ssl';
I can’t continue to unsuccessfully experiment forever as I am afraid sending lots of Spam emails will get me in trouble, so I am hoping someone can tell what I am doing wrong, or even if my overall strategy is flawed. I wish also there was a way to get the header that PHPMailer is going to use before it actually sends out the mail.
Note: my organization is a charitable group with little money, so we can't afford paid SMTP's. I've tried using the free versions of some on the market (not for the above project) but given you are using a shared IP with many others using the free service you often get emails kicked back because others sharing your IP have been Spam tagged
Thanks
This is the entire header (I deleted some of the content just to keep this note a bit brief) that I received to my personal email (b...#....com) from my "forward email" script which uses everybody#....org as the originating address. You can see the Content_Type I added to PHPMailer via $mail->addCustomHeader("Content-Type", $content_type . " boundary=" . $boundary);(which is the multipart.. line) and the one PHPMailer itself added (text/plain...). The email was received fine and displayed properly except for the Spam added to the Subject line:
From - Sat Mar 25 12:51:13 2017
STUFF
Return-Path: <everybody#....org>
Received: from dnvrco-pub-iedge-vip.email.rr.com ([107.14.70.244])
by dnvrco-fep06.email.rr.com
(InterMail vM.8.04.03.24 201-2389-100-172-20151028) with ESMTP
id <20170325165112.EUNA23395.dnvrco-fep06.email.rr.com#dnvrco-pub-iedge-vip.email.rr.com>
for <bmadder#...>; Sat, 25 Mar 2017 16:51:12 +0000
Return-Path: <everybody#....org>
Received: from [173.205.126.142] ...
Received: from ecbiz194.inmotionhosting.com .....
Date: Sat, 25 Mar 2017 12:51:01 -0400
To: b...#....com
From: everybody#....org
Message-ID: ...
Content-Type: multipart/alternative; boundary="------------3D4FAACFC2C069EFCDAE6DC6"
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
X-OutGoing-Spam-Status: No, score=-1.0
X-AntiAbuse:...
X-Get-Message-Sender-Via: ecbiz194.inmotionhosting.com: authenticated_id: everybody#....org
X-Authenticated-Sender: ecbiz194.inmotionhosting.com: everybody#....org
X-Source:
X-Source-Args:
X-Source-Dir:
X-Authority-Analysis: v=2.1 cv=Od5ldUnY c=1 sm=1 tr=0 p=tHMjoff1TzQA:10 a=BPsZ5WN3F+ptBTNoNLYonA==:117 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=9+rZDBEiDlHhcck0kWbJtElFXBc=:19 a=6Iz7jQTuP9IA:10 a=FqPqrT7mAAAA:8 a=wuaQj91YKeLcW_I7NZUA:9 a=FtJ_xtNkBE-qfxEx:21 a=wPNLvfGTeEIA:10 a=yozH4VhRfl4A:10 a=M3AHoUkWFckA:10 a=fZGknuNN1LOydenUCIb6:22
X-Cloudmark-Score: 100
X-RR-Connecting-IP: 107.14.64.106:25
Subject: SPAM: Lots of work today
X-Brightmail-Tracker: AAAAARZYL6Q=
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrDqMTGxcIABLocC65FGFx/aGGx78B3FgdGj+Mv3jMFMEZx+OWXKAQXJOYmcGT07L7AVsBQAaIaGBlWMSqUlBYbF2cUJxYVF6RWGJjrpacW6xVX5ibmlaQm6yXn525ihJq+g3H7RZlTjJJS4ry3512LEBIoBpqYUQpUVxRfVJqTWvyKUZyDUUmYNxcky5OZV1KcmQ6TkeBgUhLhNdl4JUKIt7gkESEl1cDY81CZ25t3k/zUd21bd90/typmy6NtErw+Xs/YlXtk7atb4j4+/t6yoHDeJ3uN/kP1P7LrIiY5fFipZfynvvPJzbNfz943kPtyweqk3Tn/vpOfGIosVIpPxHht7j+Rl24XEH2vJa1o/q3fJRonvyxi6D4x60xlW8M/o0oLBlvjw4672ZjKQg2UWIozEg21mIuKEwGcu2V6TwEAAA==
This is a multi-part message in MIME format.
--------------3D4FAACFC2C069EFCDAE6DC6
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
This is the text message
--------------3D4FAACFC2C069EFCDAE6DC6
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>This is the text message <br>
</p>
</body>
</html>
--------------3D4FAACFC2C069EFCDAE6DC6--
I now have the solution. Rather than using the line of $mail->addCustomHeader("Content-Type", $content_type . " boundary=" . $boundary);, I appended the variable $boundary to the variable $content_type and used $mail->ContentType = $content_type; My mail forward script now works perfectly with the Spam label no longer an issue. The header that is sent to the final recipients no longer has duplicate Content-Types listed in the MIME part
I'm sending mail and using the wordpress SMTP plugin, however I have a problem that each time I send mail, on the debugging output I see the X-Priority header being sent which makes my MQS to drop with SpamAssassin.
I've set $phhmailer->SMTPDebug=false; and setting priority to null but it doesn't change anything.
The part of debug output looks like this:
["MIMEHeader":protected]=>
string(443) "Date: Tue, 5 Apr 2016 08:44:48 +0000
Return-Path:
To: web-z4CIb1#mail-tester.com
From: Example
Subject: WP Mail SMTP: Test mail to web-z4CIb1#mail-tester.com
Message-ID: <2edb8cb56706f6d09a29b49a66cf1ff0#example.com>
X-Priority:
X-Mailer: PHPMailer 5.2.7 (https://github.com/PHPMailer/PHPMailer/)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
After quite a bit of poking around I managed to fix the issue by opening up the phpmailer class file, and commented out the following line:
$result .= $this->headerLine('X-Priority', $this->Priority);
This removed the X-Priority header completely.
If X-priority is removed from the header the email will be handled as priority 2 (normal). Instead of removing the header item, could you set it to 2?
You should be able to unset the header by using $mail->Priority = null;
according to this closed issue over at GitHub.
There can be other things affecting your spam score as well, not only the empty Priority variable.
Setting the $mail->Priority = null; is the correct solution (or do not set it at all as the default is null). However, in order for it to work you will also need to make sure you have a version of PHPMailer that has been updated with this patch.
I am using Mailgun API based extension in Expression engine CMS When i disable the Mail-gun its sending perfect html mail but when I enable Mailgun its sending Email like in this manner:
This is a multi-part message in MIME format.
Your email application may not support this format.
--B_ALT_565e9f7740811
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
HELLO this is a message
--B_ALT_565e9f7740811
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<b>HELLO</b> this is a message
--B_ALT_565e9f7740811--
I type only once "HELLO this is a message" in this manner:
<b>HELLO</b> this is a message
But its showing two times in the email please resolve this issue.
I had so much headache with sending though an API I ended up buying Escort (https://devot-ee.com/add-ons/escort) and it simply worked perfectly and saved a lot of time making it worth it. I use it with Mandrill, but it supports yours.
Hope this kind of answer is allowed, as I know it isn't directly solving your problem.
TL;DR: Mails sent from shared hosting (such as a cheap domain from Unoeuro or One.com) end up in spam. How to fix?
I made a mail-system, that first generated a PDF-file (using FPDF), whereafter it sent the PDF-file as an attachment with PHP's Swiftmailer. This email was sent out to 130 people (as a 'one-of' invoice). But it landed in the spam-filter for almost everybody. I tried adjusting SwiftMailers header-settings, but without any luck. Even mails that I haven't sent to before (thoroughly tested). This was my initial setup:
function sendMailEt($toEmail, $toName, $invoiceNumber){
require_once('includes/lib/swift_required.php');
$transport = Swift_SmtpTransport::newInstance('mailout.one.com', 25)
->setUsername('EMAIL-ACCOUNT1#THE-DOMAIN.DK')
->setPassword('THE-PASSWORD')
;
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance('FROM COMPANY')
->setSubject('Thanks for signing up - COMPANY')
->setFrom(array('EMAIL-ACCOUNT1#THE-DOMAIN.DK' => 'Company name'))
->setTo(array($toEmail => $toName))
->setBody('A brief body, that explains that this is an invoice and that it has to be paid within 5 days. (written in danish)')
->addPart('A brief body, that explains that this is an invoice and that it has to be paid within 5 days. (written in danish)', 'text/html')
->attach(Swift_Attachment::fromPath('/URL-TO-THE-PDF-FILE.pdf'))
;
$result = $mailer->send($message);
}
I also tried sending out the emails with PHP's native mail()-function, and then simply link to the invoice ( http://www.company-domain-name.dk/invoice/base64_encoded-name.pdf )... Same result (spam).
I tried writing the entire header myself. I've read a numerous amount of forums about what headers should include, but they all wrote different things. So I tried a few different things (both emails I had sent to previously and emails I hadn't)... Same result (spam).
Then I tried writing the header exactly as MailChimps does, in their header. That led me to this:
$headers = "Reply-To: Company name <UNUSED-EMAIL-ACCOUNT-FROM-DOMAIN#DOMAIN-NAME.DK>\r\n";
$headers .= "Return-Path: Company name <UNUSED-EMAIL-ACCOUNT-FROM-DOMAIN#DOMAIN-NAME.DK>\r\n";
$headers .= "From: Message from Company name <UNUSED-EMAIL-ACCOUNT-FROM-DOMAIN#DOMAIN-NAME.DK>\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Sender: Message from Company name <UNUSED-EMAIL-ACCOUNT-FROM-DOMAIN#DOMAIN-NAME.DK>\r\n";
$headers .= "Content-type: text/plain; charset=\"utf-8\"; \r\n";
$headers .= "X-Mailer: PHP". phpversion() ."\r\n";
And then I send the mail like this:
mail($toName . '<'.$toEmail.'>', utf8_decode('Faktura på depositumet'), utf8_decode($someMessage), $headers);
... Same result (spam).
The webspace is with One.com, so I can't use PHPmailer (since that has to be installed, and that can't be done on one.com's servers). And I can't define a SPF with One.com.
All I want, is to be able to send emails that doesn't go to spam.
Here are my questions:
Is it because my header is off, or is it something 'deeper down'?
Does the Gmail-spam filter ban single email accounts (such as
this#example.com) or does it ban entire domains (such as
#example.com)?
Can one get a blacklisted email whitelisted
somehow?
* Addition 1 *
Ok... I have now tried a number of things:
I tried adding LoneWolfPR's returnpath, like recommended, and it didn't help.
I contacted One.com (the hosting company), and confirmed with them, that it isn't possible to set a SPF-record or a DKIM-record. It still isn't.
I considered setting up an 'unsubscribe'-link, with a link to a website with a form, but I didn't believe that approach. I mean - invoices are sent all the time, with e-mails. And why should you be able to unsubscribe an invoice?! Since that made so far from sense in my head, then I only tried it for about 20 minutes (obviously, without results).
Here is my current email header (gotten from Gmail, by clicking the 'View original'):
Delivered-To: NEWLY-CREATED-GMAIL-ACCOUNT#gmail.com
Received: by 10.76.75.104 with SMTP id b8csp48728oaw;
Sat, 16 Mar 2013 17:32:56 -0700 (PDT)
X-Received: by 10.152.116.45 with SMTP id jt13mr7897860lab.0.1363480376067;
Sat, 16 Mar 2013 17:32:56 -0700 (PDT)
Return-Path: <XXX111#DOMAIN-NAME.dk>
Received: from mail-out2.b-one.net (mail-out2.one.com. [91.198.169.19])
by mx.google.com with ESMTP id p10si4637427lbb.120.2013.03.16.17.32.55;
Sat, 16 Mar 2013 17:32:55 -0700 (PDT)
Received-SPF: neutral (google.com: 91.198.169.19 is neither permitted nor denied by best guess record for domain of XXX111#DOMAIN-NAME.dk) client-ip=91.198.169.19;
Authentication-Results: mx.google.com;
spf=neutral (google.com: 91.198.169.19 is neither permitted nor denied by best guess record for domain of XXX111#DOMAIN-NAME.dk) smtp.mail=XXX111#DOMAIN-NAME.dk
Date: Sat, 16 Mar 2013 17:32:55 -0700 (PDT)
Message-Id: <51450f37.6a0b700a.6239.5dbcSMTPIN_ADDED_MISSING#mx.google.com>
Received: from localhost.localdomain (srv18.one.com [193.202.110.18])
by mail-out2.b-one.net (Postfix) with ESMTP id F3D0B10365
for <NEWLY-CREATED-GMAIL-ACCOUNT#gmail.com>; Sun, 17 Mar 2013 01:32:53 +0100 (CET)
Received: from 85.218.159.219 by www.DOMAIN-NAME.dk via URL_TO_THE_SCRIPT.php with HTTP; Sun, 17 Mar 2013 00:32:53 +0000
To: RECIEVERS_NAME <NEWLY-CREATED-GMAIL-ACCOUNT#gmail.com>
Subject: EMAIL-SUBJECT
X-PHP-Originating-Script: 87486:NAME-OF-THE-SCRIPT-THE-E-MAIL-WAS-SENT-FROM.php
Reply-To: COMPANY NAME <XXX111#DOMAIN-NAME.dk>
From: Besked fra COMPANY NAME <XXX111#DOMAIN-NAME.dk>
MIME-Version: 1.0
Sender: Besked fra COMPANY NAME <XXX111#DOMAIN-NAME.dk>
Content-type: text/plain; charset="utf-8";
X-Mailer: PHP5.3.21
1) Normally an email address won't go easily into a blacklist, it takes time and/or a lot of people to tag you as spammer to actually get that address into a blacklist.
2) Yes. A whole domain name can be blacklisted, because spammers normally generate random email addresses like f4j3ifl#something.com.
3) It doesn't matter how many times it went to the spambox, basically, the spam filters nowadays are strong, because spammers try to improve their ways to get around day by day, so the filters gets more strict every day. If it goes into spam folder first time, and the user didn't actually put it into the spam box, it will continue going unless users unmark it, or you fix the troubles.
How to avoid spambox?
Basically you need some signatures, and a lot of access to your DNS records, because there is where we are going to do most of the setups.
Reverse DNS Lookup: On dedicated servers or even on some VPS you are able to set up a reverse dns record, sometimes you just open a ticket and the IT's set it up for you. If you can't have it, change your hosting or keep being tagged as spammer xD. This is to preven header forgeries, as you could set on your headers that your email comes from gmail.com but it doesn't this is the way the email servers check it.
SPF is a must have as well, if you can't set a SPF then don't even try any further, consider changing your hosting, and you can almost stop reading by here xD.
DKIM/Domain Key: preferably DKIM, is a encrypted signature, you set the public key on the DNS, and store a private key in your email server, when a server receives an email, it has the private key attached in the headers (you need a mailserver software which manages DKIM, for windows for example it worked for me hmailserver) and the mail service (gmail for example) will check your dns record to see if the public key matches. This is almost a must have as well
Those three were the basics, if you Set up DMARC and ADSP it will get you better score for the SpamAssassins. To get a even better score search for some spam keywords lists on google and try to avoid them, some stuff like starting an email with "Dear xxx" are harmful for your score, Set up the unsuscribe system(even if it's crappy, as long as you provide a clear link) will help you a bit as well.
Also:
Avoid sloppy html and white text over (any) backgrounds, some spammers use it to fit in hidden text, those filters are smarter than you think.
Read the specific recommendations. Most email services have a FAQ or something in their website with some tips to help you sending emails and not going into the junk. on Some of them you can even apply for getting into a white list ( at least some years ago, on some services like gmail they don't do it anymore)
If you are sending in bulk, watch the time! If you have X emails per second sent into somewhere, you are likely to get into blacklist, set up a script or something to get a 1sec delay or so, the delay might depend on the destinatary to get into the blacklist or not.
Hope those tips help you, I had to deal with some spam filters recently and it's a pain in the ass, that's why I know all that info, that's all my research xD Even after all the signatures and things I have set up, some of the emails are still going into spambox(a smaller percentage but it still hurts me) The only reliable way is to get the users adding you to the contacts list (while having the signatures and headers correctly), so remind them to do so if possible.
One thing to bear in mind, I had trouble with emails being blocked by Gmail and Yahoo! mail from php because the Return-Path header didn't match the from. On a lot of servers if you explicitly set the Return-Path in the headers PHP Mail will ignore that and set the return path to the machine name. You have to force it in the 'additional parameters' section of the mail function using the '-f' flag. Now I've never used Swift Mailer so I don't know the equivalent to PHP's native mail() function, but here's what it would look like using mail();
mail($to,$subject,$message,$headers,'-f returnpath#example.com')
If you can find out the equivalent to this in swift mailer it might solve your problem.
Edit:
It looks like you're not actually setting the Return-Path at all. I know GMail really doesn't like that to be left out. Try setting it explicitly to your Swift_Mailer message (and make sure it matches your From):
$message->setReturnPath('from#example.com');
Solution: Use Mailgun (not tested) or Sendgrid (tested and works wonders!). There is a price-difference between the two, - but in short: Mailgun is good if you're small; Sendgrid is good if you're big.
Either that, - or send mails using MailChimps API or something. It's can't be fixed on shared hosts (most likely). The reason is below.
Explanation: I've later learned more about how shared hosts work. Imagine that several different sites are located on the same server (such as domain-1.org, domain-2.org and domain-3.org). That means that if domain-3.org sends a bunch of crap-emails, then Gmail (and other spam-filters) mark that IP-address as spam. So if domain-2.org then send out stuff, then that'll (probably) come from the some IP-address and therefore end up in spam. Shared hosts can't really do anything about it (and don't care, since so few people have this problem). And that is why it's so cheap.
Sendgrid and Mailguns IP-addresses are marked as 'fine' by all the spam-filters, and that's the service that you're paying for with them. They keep it that way, by monitoring how many emails you send out are being marked as 'spam'. If it's something like 5%-10% or something crazy low, then Sendgrid/Mailgun will block your account until you fix it (going through a long process, where you have to contact their customer service and do 1.000 hail-Mary's and all kinds of wierd stuff).
I heard that if you get your own server (which is way more expensive), and set up your own mail-server, then you have to be really careful, not to be marked as spam. Cause spam-filter are really tough nowadays...
Make sure the email address you are using as the FROM is actually an email address. I have had the same issue been resolved by going into my account management from the host (one.com for you) and adding the account that I want the email to be from. I added an account called "mailer" and through the panel I was able to setup an auto-responder that said, "Sorry. This email address is reserved for server functions".
in the from header you would then use (mailer#yourdomain.com)
having that actual email address and auto-reponder did the trick. I think gmail is just smart enough to know that an email adress that has never been used before is spam. Also, the email address must come from the domain that the script lives on so that when it says it is FROM there it is not lying.
here is the code that I use when I want to send email from my shared host (justhost.com) , It does not go to spam (this is using post data from a web form):
<?php
// Contact subject
$subject = $_POST["subject"];
// Details
$message=$_POST["detail"];
// Email of sender
$mail_from=$_POST["customer_mail"];
//Name of sender
$name=$_POST["name"];
putenv("TZ=America/Phoenix");
$now = date("F j, Y, g:i a T");
$header="Reply-To: $name <$mail_from>";
$header .= "From: MyDomainName.com <mailer#mydomainname.com>";
$header .= "\r\n";
$header .= "Reply-To: $name <$mail_from>";
$introMSG= "Message From:".$name." <".$mail_from.">"."\r\n"
."Sent On:".$now."\r\n"."From a web form on MyDomaiNname.com"."\r\n"."-----------
-----------------------"."\r\n"."\r\n";
$to ='me#mydomainname.com'; // Domain Owners Email Address
$send_contact=mail($to,$subject,$introMSG.$message,$header);
$send_copy=mail($mail_from,"Copy Of:".$subject,$introMSG.$message,$header);
// Check if message sent
if($send_contact){
echo "<strong>Thanks! Your message has been sent to me.</strong>";
}
else {
echo "<strong>There was an error sending your message </strong>";
}
if($send_copy){
echo "<strong><br>A copy of this message was sent to your email.<br>If you do not
receive a copy please check your spam folder</strong>";
}
else{
echo "<strong> There was an error sending a copy of this message to your email
</strong>";
}
$send_reminder=mail("5555555555#txt.att.net","","You Have a new contact message from
".$name.", remember to check your spam folder.",$header);
if($send_reminder){
echo ".";
}
else {
echo "<br><strong>TXT Error</strong>";
}
?>
There are at least two "spammy" looking things that jump out of your email headers:
Message-Id: <51450f37.6a0b700a.6239.5dbcSMTPIN_ADDED_MISSING#mx.google.com>
Notice the SMTPIN_ADDED_MISSING section? You aren't behaving like a proper mailer and generating a unique Message-ID. You might find reading RFC 5322 to be instructional.
Received: from localhost.localdomain (srv18.one.com [193.202.110.18])
by mail-out2.b-one.net (Postfix) with ESMTP id F3D0B10365
for <NEWLY-CREATED-GMAIL-ACCOUNT#gmail.com>; Sun, 17 Mar 2013 01:32:53 +0100 (CET)
That initial received header has an illegal HELO hostname (localhost.localdomain). Your mailer app should provide a way for you to set that to a valid value. It might even be as easy as configuring the hostname of the machine running PHP. See RFC 1035 (hostname validity), RFC 2821 (SMTP) and RFC 5321 (SMTP).
I just switched from a shared server to a virtual dedicated. The whole site works, but my mail forms have quit sending MIME emails the way they used to.
What used to appear before the server switch:
hallo fwend
What appears now in the emails (appears as though my client doesn't support MIME):
Content-Type: multipart/alternative; boundary="==DL-
bound_b08bcfabdc459ae7e87e493a984115b3"
This is a multipart MIME message from
your friends at Example.com. If you
are reading this, it seems we have a
message to deliver, but your mail
client is not set to receive these
types of messages. We are sorry for
the inconvenience :(
--==DL-bound_b08bcfabdc459ae7e87e493a984115b3
Content-Type: text/plain;
charset=iso-8859-1
Content-Transfer-Encoding: 7bit
hallo fwend
Is there some switch in PHP or something that I need turned on to send MIME?
It look like the headers are send in the body part of the message.
I had this problem a while back.
Possible causes are:
1. EOL
I used "\r\n" as eol for the MIME headers (following the spec)
, but the (shared)server wanted an "\n"
2. Last header
Some mail server add some headers of their own. If the last header end with "\n" and the mail server could also mess thing up.
3. Empty header
An empty header which causes a "\n\n" in the $headers will corrupt the headers. The "\n\n" aka "empty line" marks the end of the headers part of a email (or the start of the body)