Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote host said: 552 5.2.0 Message contains bare CR and is violating 822.bis section 2.3 #3012

Open
monkeyArms opened this issue Feb 1, 2024 · 7 comments

Comments

@monkeyArms
Copy link

monkeyArms commented Feb 1, 2024

Problem description

I started receiving bounce-backs from a client recently with the error message in the title. This is on PHP 8.1.23 & PHPMailer 6.9.1.

I reduced my case down to a bare-bones example:

<?php

use PHPMailer\PHPMailer\PHPMailer;

$mail      = new PHPMailer;
$subject   = 'HTML Email Test';
$emailTo   = 'REDACTED@wp2.kscoxmail.com';
$emailFrom = 'REDACTED@example.com';
$emailSubject     = $subject;
$emailMessageBody = '<p><b>HTML Mail</b> Test</p>';
$emailHTML        = '
			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html lang="en">
				<head>
					<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
					<title>'.$emailSubject.'</title>
				</head>
				<body>
					'.$emailMessageBody.'
				</body>
			</html>
		';

$mail->IsHTML();
$mail->CharSet  = 'UTF-8';
$mail->Priority = 3;
$mail->AddAddress( $emailTo );
$mail->From = $emailFrom;
$mail->AddReplyTo( $emailFrom );
$mail->Subject = $emailSubject;
$mail->Body    = $emailHTML;

$result = $mail->Send();

var_dump( $result );

While this works for 99% of recipients, from this one particular client I receive the following failure notice reply:


Hi. This is the qmail-send program at REDACTED.com.
I'm afraid I wasn't able to deliver your message to the following addresses.
This is a permanent error; I've given up. Sorry it didn't work out.

<REDACTED@wp2.kscoxmail.com>:
DKIM signed ok
REDACTED_IP failed after I sent the message.
Remote host said: 552 5.2.0 Message contains bare CR and is violating 822.bis section 2.3

--- Below this line is a copy of the message.

Return-Path: <REDACTED@example.com>
Received: (qmail 45014 invoked by uid 875); 1 Feb 2024 18:28:52 -0000
To: REDACTED@wp2.kscoxmail.com
Subject: HTML Email Test
X-PHP-Script: REDACTED.com/index.php for REDACTED_IP
Date: Thu, 1 Feb 2024 13:28:52 -0500
From: REDACTED@example.com
Reply-To: REDACTED@example.com
Message-ID: <vfMbfphUy6GKoRESBY7tssb8WbO0dlQSxTef1ddV2A@REDACTED@example.com>
X-Priority: 3
X-Mailer: PHPMailer 6.9.1 (https://github.com/PHPMailer/PHPMailer)
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8



			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html lang="en">
				<head>
					<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
					<title>HTML Email Test</title>
				</head>
				<body>
					<p><strong>HTML Mail</strong> Test</p>
				</body>
			</html>



@Synchro
Copy link
Member

Synchro commented Feb 1, 2024

That's a little strange! Bare CRs are only really associated with very old MacOS systems, but here it looks like it might be something that you have introduced in your message body - does it bounce in the same way if you use a minimal body, like 'test'?
Line breaks can also be problematic when using PHP's mail() function, which you're effectively using here (it's PHPMailer's default transport), because Linux sendmail binaries like to have bare LF line breaks (even thought this is an RFC contravention), so we have to jump through hoops to do line break conversions. It might be worth switching to $mail->isSMTP() so that it sends via SMTP instead (but will still go through your local mail server), as this doesn't have to do anything odd with line breaks.

Line break problems are often hard to debug because editors and web forms have a habit of altering them invisibly, but we'll cross that bridge if switching to SMTP doesn't solve it.

@monkeyArms
Copy link
Author

Thanks for your comment. I tried changing the message body to simply "Test", but received the same failure notice.

Using SMTP as you suggested did allow the mail to be delivered:

<?php

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;

/**
 * @param PHPMailer $mail
 *
 * @return void
 */
function useSMTP( PHPMailer $mail ) : void
{
	$mail->SMTPDebug = SMTP::DEBUG_SERVER;
	$mail->isSMTP();
	$mail->Host       = 'REDACTED.example.com';
	$mail->SMTPAuth   = true;
	$mail->Username   = 'REDACTED@example.com';
	$mail->Password   = 'REDACTED';
	$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
	$mail->Port       = 465;
}


$mail         = new PHPMailer;
$emailTo      = 'REDACTED@wp2.kscoxmail.com';
$emailFrom    = 'REDACTED@example.com';
$emailSubject = 'Test';
$emailHTML    = 'Test';

$mail->IsHTML();
$mail->CharSet  = 'UTF-8';
$mail->Priority = 3;
$mail->AddAddress( $emailTo );
$mail->From = $emailFrom;
$mail->AddReplyTo( $emailFrom );
$mail->Subject = $emailSubject;
$mail->Body    = $emailHTML;

// if the line below is left out, the mail bounces back with "Remote host said: 552 5.2.0 Message contains bare CR and is violating 822.bis section 2.3"
useSMTP( $mail );

$result = $mail->Send();

var_dump( $result );

I haven't been able to test this on other PHP versions yet, so no idea if that is related to the issue or not.

@Synchro
Copy link
Member

Synchro commented Feb 1, 2024

I'm glad you've got that working. Without a bit-perfect copy of the submitted message this is difficult to diagnose any further.

@monkeyArms
Copy link
Author

monkeyArms commented Feb 5, 2024

I did some more testing in different PHP versions (on linux, using the default sendmail instead of SMTP), and the emails go fine with version 7.4, but not 8.0, 8.1, 8.2 or 8.3.

I changed my sendmail_path INI setting from /var/qmail/bin/sendmail -t -i to tee /some/path/mail.txt, and that shows that the line breaks being sent to sendmail from PHP 7.4 and below are \n, while 8.0 and higher are now \r\n:

PHP 7.4:

To: redacted@example.com\n
Subject: Test\n
X-PHP-Script: redacted.example.com/index.php for REDACTED\n
Date: Mon, 5 Feb 2024 15:51:13 -0500\n
From: redacted@example.com\n
Reply-To: redacted@example.com\n
Message-ID: <3mMl9iKZhvSwfkXwoWLVOCPmsJ1nHUmla4CpHWDzCo@redacted.example.com>\n
X-Priority: 3\n
X-Mailer: PHPMailer 6.9.1 (https://github.com/PHPMailer/PHPMailer)\n
MIME-Version: 1.0\n
Content-Type: text/html; charset=UTF-8\n
\n
Test\n
\n

PHP 8.x:

To: redacted@example.com\r\n
Subject: Test\r\n
X-PHP-Script: redacted.example.com/index.php for REDACTED\r\n
Date: Mon, 5 Feb 2024 15:30:56 -0500\r\n
From: redacted@example.com\r\n
Reply-To: redacted@example.com\r\n
Message-ID: <AKbekIllGG83EzcNtpYo3Y86xOgMICDIpFjmqFBfpY@redacted.example.com>\r\n
X-Priority: 3\r\n
X-Mailer: PHPMailer 6.9.1 (https://github.com/PHPMailer/PHPMailer)\r\n
MIME-Version: 1.0\r\n
Content-Type: text/html; charset=UTF-8\r\n
\r\n
Test\r\n
\r\n

I don't know how to capture the raw output of sendmail, but from what I can tell sendmail expects line breaks to be \n, but PHP's mail() now outputs /r/n in versions 8.x. I suspect sendmail is mangling the line breaks due to being fed CRLF data.

Some interesting threads I found:

So I think this is an issue between PHP and sendmail, from what I can tell. If so I'm not sure there's anything that can be done on PHPMailer's part.

@Synchro
Copy link
Member

Synchro commented Feb 5, 2024

Good research, thank you. Wow, that second link! Somehow this had passed me by, and that's a pretty major breaking change. I'm surprised others are not having similar issues.

Historically, it has been annoying that mail() uses platform line breaks, and there was a major rewrite of how that was handled in PHPMailer 6.0; it was horribly inconsistent prior to that. One of the changes was to set the line break format in only one place, which is in the PHPMailer::$LE static class property. That's protected, so you'll need to subclass to change it, but it should go like this if you want to force the line break format to \n:

use PHPMailer\PHPMailer\PHPMailer;

class MyMail extends PHPMailer
{
    static $LE = "\n";
}

then use that class instead of the stock PHPMailer. Give that a try!

@monkeyArms
Copy link
Author

monkeyArms commented Feb 12, 2024

I finally had some time to test out the subclass with \n line endings, and unfortunately it doesn't change anything. The output still has CRLF breaks. mail() in PHP 8.x now just replaces any line breaks you feed it with \r\n.

@derStephan
Copy link

The mail() feature is broken in recent PHP versions. If you control this server, try setting the sendmail_path to remove CRs from whatever PHP is handing over to the mail agent.

sendmail_path='/usr/bin/dos2unix -u|/usr/sbin/sendmail -t -i'

Needs dos2unix to work. I tested this even with HTML mails and UTF-8 characters. Works in all cases for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants