Troubleshooting

How to turn on PHPMailer debug mode and diagnose SMTP errors

Reviewed on 4 min read depuracion smtp

PHPMailer debug mode shows the SMTP conversation between the application and the mail server. It is the most direct way to tell a connection, TLS, authentication or message rejection failure apart.

Turn it on only while you reproduce the problem, with a test recipient and test content. The transcript may include senders, recipients, headers and the message body. Levels 0 to 3 hide the SMTP username and password, but SMTP::DEBUG_LOWLEVEL may show them. Don't publish the full output.

In PHPMailer 6 and 7, import the classes and use the SMTP::DEBUG_SERVER constant, equivalent to level 2 in older versions:

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

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->SMTPDebug = SMTP::DEBUG_SERVER;

Add these options to the PHPMailer instance your application already sends with, after loading its classes and before calling send(). The snippet isn't a complete sending program: keep your server, authentication and test recipient settings.

This level logs both the commands sent by the client and the server's responses. Level 3 adds information about the initial connection and can help when there is a timeout. Level 4 shows low-level traffic, can reveal the SMTP credentials and shouldn't be used except to analyse a protocol problem in a controlled environment.

If you don't want the transcript shown in the HTML response and PHP's error_log already points to a private log outside public_html, you can send it there:

$mail->Debugoutput = 'error_log';

Don't use this output without first checking where PHP writes: it could end up in a shared log or one that can be downloaded from the web.

When you finish, turn off diagnostics and delete the log once you no longer need it:

$mail->SMTPDebug = SMTP::DEBUG_OFF;

How to read the output

Look for the server's last response before the failure:

  • No 220 response appears: check the server name, DNS, port and possible network blocks.
  • STARTTLS or certificate validation fails: check that TLS and port match, that the OpenSSL extension is enabled and that the system has up-to-date CA certificates. Don't turn off TLS verification to hide the error.
  • 535 or similar response: the server rejected authentication. Check the full username, the password and the method the provider supports.
  • 550 or 5.7.x response: the server received the request but rejected the sender, the recipient or the message. Keep the full text, as it usually states the policy applied.
  • 250 response at the end of DATA: the server accepted the message for processing. An earlier 250, for example after EHLO or MAIL FROM, doesn't confirm the complete send. Acceptance doesn't guarantee delivery to the inbox either. If it then shows up in spam, continue with the deliverability guide.

The official PHPMailer troubleshooting guide recommends using current examples, reading the full SMTP transcript and checking the network before blaming the library.

Useful details for reproducing the failure

Keep the PHPMailer version, the PHP version, the SMTP host and port, the encryption type and the full error message. Replace any private address, token or credential first. A screenshot that only shows SMTP connect() failed usually hides the response that lets you find the cause.

You may also find useful

Something wrong or out of date? Tell us and we will review it.