A contact form sends a message, WordPress shows "Message sent," and the email never arrives in the inbox. The cause is almost always the same: the standard PHP mail() function is not fit for delivering email from a production site. Here is how to switch to SMTP and why that fixes the problem.
Why WordPress emails do not reach the recipient
By default, WordPress sends email through the PHP mail() function, which hands the message to the server's local mail agent with no authentication and no digital signature. Mail services like Gmail and Outlook see a message with no SPF, DKIM, or DMARC records for the sender domain and quietly route it to spam or reject it outright. WooCommerce stores suffer separately: order confirmation emails fail to arrive the same way regular notifications do — store setup is covered in the article WooCommerce: setting up an online store on WordPress.
The second common cause is the hosting provider blocking outbound port 25 to stop the server from being used for spam. In that case mail() reports "message sent" even though the message never actually left.
How to check what exactly is breaking delivery
Install the WP Mail SMTP or Check Email plugin — this can also be done with a single terminal command instead of the admin panel, as described in the article WP-CLI: managing WordPress from the command line — and send a test message through the check section in the plugin's settings. The plugin shows the mail server's response code, which reveals whether the server rejected the connection, the port, or the authentication.
You can check port 25 from the server with:
# Check whether port 25 responds on outbound connections
telnet smtp.gmail.com 25
If the connection hangs with no response, the port is blocked at the network level, and you should use port 587 or 465 with encryption instead.
Setting up SMTP with the WP Mail SMTP plugin
The most reliable approach is sending mail through an external SMTP server: a mailbox on your own domain, Gmail, SendGrid, or Mailgun. Setup through the WP Mail SMTP plugin:
- Install and activate the WP Mail SMTP plugin.
- Choose a mail provider — for example, Other SMTP for a mailbox on your own domain.
- Enter the SMTP host, port 587, TLS encryption, and the mailbox login and password.
- Send a test email through the plugin's built-in check.
Table of typical connection settings for different ports:
| Port | Encryption | When to use it |
|---|---|---|
| 587 | TLS (STARTTLS) | the recommended option for most mail servers |
| 465 | SSL | when the provider requires encryption right at connection time |
| 25 | no encryption | do not use for authenticated sending |
Setting it up through wp-config.php without a plugin
When plugins are not welcome on the site, SMTP can be wired through the phpmailer_init hook in the theme file or in a separate mu-plugin:
add_action( 'phpmailer_init', function( $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = 'smtp.example.com';
$phpmailer->Port = 587;
$phpmailer->SMTPAuth = true;
$phpmailer->Username = 'noreply@example.com';
$phpmailer->Password = 'secret-in-environment-variables';
$phpmailer->SMTPSecure = 'tls';
} );
A password in code is bad practice; store it in the server's environment variables instead of the theme file.
DKIM, SPF, and the sender domain's reputation
Even correct SMTP settings will not help if the domain has no SPF and DKIM records in DNS. An SPF record tells mail servers which IP addresses are allowed to send email on behalf of the domain, and DKIM adds a digital signature to every message. Without these records, mail from a mailbox on your own domain will still land in spam for some recipients.
Add an SPF record like v=spf1 include:example.com ~all to the domain's DNS zone and enable DKIM in the mail control panel — this is usually a single checkbox in the mail domains section in ISPmanager 6 or cPanel. A mailbox password is just as much a secret as an admin password; the full list of site protection measures is collected in the article WordPress Security: Complete 2026 Checklist.
WordPress mail setup checklist
Before closing out the task, check:
- The WP Mail SMTP plugin or the
phpmailer_inithook is connected and configured. - Port 587 with TLS or 465 with SSL is used instead of port 25.
- A test email was actually received, not just reported as "sent" in WordPress.
- SPF and DKIM records are added to the domain's DNS.
- The mailbox password is not stored as plain text in the theme code.