SYSTEMS OPERATIONAL
WordPress

WordPress Not Sending Emails? Fix It with SMTP

Getwebup 6 min read

You fill out your own contact form to test it, hit submit, and nothing shows up. Or a customer says they never got their order confirmation, or you reset your own WordPress password and the email just never lands. This is one of the most common WordPress support tickets we see, and it's almost never a bug in your theme or plugin — it's how WordPress sends mail in the first place.

Symptom: forms submit fine, but the email never arrives

A few patterns that all point to the same root cause:

  • Contact Form 7, WPForms, or Gravity Forms shows "message sent" but the inbox stays empty
  • WooCommerce order confirmations don't reach customers (or you)
  • "Lost your password?" never delivers a reset link
  • New user registration emails don't go out
  • Emails work sometimes and randomly stop, with no error visible in WordPress itself

WordPress itself never tells you it failed — the form plugin just says "sent" because, as far as PHP is concerned, it handed the message off. What happens after that is the problem.

Cause: WordPress uses PHP's mail() function by default

Unless a plugin changes it, every wp_mail() call in WordPress goes through PHP's built-in mail() function, which hands the message to your server's local mail transfer agent (usually Exim or Sendmail on cPanel, Postfix elsewhere) and walks away. It doesn't wait to confirm delivery, and it doesn't retry.

That's unreliable for a few concrete reasons:

  • No authentication. Mail sent this way often has no DKIM signature and a mismatched "From" domain, so Gmail, Outlook, and Yahoo silently drop it or bin it as spam — see our SPF/DKIM/DMARC guide if that's the exact symptom you're seeing on emails that do arrive.
  • Shared IP reputation. On shared hosting, your server's outbound IP is sending mail for hundreds of other accounts. If even one of them gets flagged as a spam source, everyone's local mail() delivery suffers.
  • No delivery confirmation. If Exim rejects the message locally or a receiving server bounces it, WordPress never finds out. The plugin still shows "success."
  • Some hosts block outbound port 25 entirely to stop spam abuse, which kills local mail() delivery outright.

Fix: send mail through real SMTP instead of local mail()

The fix is always the same shape: stop using PHP mail() and route wp_mail() through an authenticated SMTP connection instead. That gives you a real username/password handshake, a verified sending domain, and actual error messages when something goes wrong.

Step 1: Pick where your mail will actually send from

You need an SMTP account to send through. Three common options:

OptionGood forNotes
A cPanel email account on your domainLow-volume sites, quick fixUse mail.yourdomain.com, port 465 (SSL) or 587 (TLS), with the full email as username
Google Workspace / GmailSmall sites already using Gmail for business emailRequires an app password, not your normal login password; capped around 500 emails/day
A transactional provider (Brevo, SendGrid, Amazon SES, Mailgun)Stores, membership sites, anything sending password resets or receipts at volumeBest deliverability and analytics; free tiers cover most small sites

If you're already fighting spam-folder issues on a domain with SPF/DKIM set up, sending through a transactional provider that manages its own authenticated sending domain is usually the least troublesome long-term option.

Step 2: Install an SMTP plugin and connect it

Install WP Mail SMTP or FluentSMTP (both free, both solid) from Plugins → Add New. Then:

  1. Go to the plugin's settings and choose your mailer (Other SMTP, Gmail, Brevo, SES, etc.)
  2. Enter the SMTP host, port, and encryption type from your provider or cPanel → Email Accounts → Connect Devices
  3. Enter the SMTP username (usually the full email address) and password or app password
  4. Set the "From" email to an address on your own domain — not a Gmail address, which will fail SPF checks
  5. Save, then use the plugin's built-in "Send a Test Email" tool

If the test email arrives, you're done — every plugin using wp_mail() now routes through SMTP automatically, no code changes needed.

Step 3: If you'd rather not add a plugin, do it in code

You can hook into phpmailer_init in your theme's functions.php (or better, a small must-use plugin) to force SMTP without a UI plugin:

add_action( 'phpmailer_init', function( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = 'mail.yourdomain.com';
    $phpmailer->SMTPAuth   = true;
    $phpmailer->Port       = 587;
    $phpmailer->Username   = 'noreply@yourdomain.com';
    $phpmailer->Password   = 'your-mailbox-password';
    $phpmailer->SMTPSecure = 'tls';
    $phpmailer->From       = 'noreply@yourdomain.com';
    $phpmailer->FromName   = get_bloginfo( 'name' );
} );

Storing a password in plain PHP isn't ideal for anything beyond a quick fix — for production, pull it from an environment variable or stick with the plugin, which stores credentials more sensibly.

Still not arriving? Check the server, not WordPress

If SMTP is configured correctly and mail still doesn't show up, the problem has moved past WordPress:

  • On cPanel, check Email → Track Delivery to see exactly what happened to a specific message — delivered, deferred, or bounced, with the receiving server's response.
  • On a VPS, tail the mail log directly: tail -f /var/log/exim_mainlog (Exim) or tail -f /var/log/mail.log (Postfix) while you send a test.
  • Test the SMTP connection independently of WordPress: telnet mail.yourdomain.com 587 should connect and return a 220 banner. If it hangs or refuses, your host or firewall is blocking that port — check whether outbound SMTP ports are open under your VPS firewall rules.
  • Check the recipient's spam folder before assuming delivery failed — it's the most common false alarm.

It's not always SMTP — two other common causes

Occasionally the fix above doesn't apply because the real issue is somewhere else entirely:

  • A caching or security plugin is stripping the email. Some aggressive security plugins block wp_mail() outright as a hardening measure. Temporarily deactivate plugins one at a time to isolate it.
  • Another plugin has already overridden wp_mail(). Only one plugin can cleanly own the wp_mail function via pluggable.php. If you have two SMTP or mail-related plugins active at once, deactivate all but one — they conflict silently rather than throwing an error.

Prevention

  • Set up SMTP once, right after launch, before you assume the default mail() setup is fine — don't wait for a lost sale to find out it wasn't
  • Use a "From" address on your own verified domain, never a free Gmail/Yahoo address, so SPF/DKIM checks pass
  • Send a real test email after any plugin update that touches mail, forms, or security settings
  • Keep only one SMTP/mail plugin active at a time
  • For stores or membership sites, use a transactional provider with delivery logs so you can actually see what happened to a message instead of guessing

Frequently asked questions

Why does my contact form say "message sent" if the email never arrives?

Because the form plugin only confirms that PHP handed the message to the server's local mail agent, not that it was actually delivered. WordPress has no way of knowing what happened after that unless you're using SMTP with proper error reporting.

Do I need a paid service to fix WordPress email delivery?

No. A cPanel email account on your own domain works fine for low-volume sites and is already included in your hosting. For stores or higher-volume sending, a transactional provider's free tier (Brevo, SendGrid, Amazon SES) is usually enough and gives you delivery logs.

I set up SMTP but emails still land in spam. What's next?

SMTP fixes delivery reliability, but spam placement is a separate, DNS-level issue. Check that SPF, DKIM, and DMARC records are correctly published for your sending domain.

Can I use my personal Gmail account for SMTP?

You can, using an app password, but it's capped around 500 emails/day and Google may flag automated sending from a personal account. It's fine for testing or a very small site, not for a store or membership site.

How do I know if my host is blocking outbound mail entirely?

Run telnet mail.yourdomain.com 587 (or 465/25) from your own machine or the server itself. If the connection hangs or is refused instead of returning a banner, the port is being blocked and you'll need to check your VPS firewall rules or ask your host to open it.

#wordpress #smtp #email-delivery #wp-mail-smtp #contact-form #troubleshooting

Keep reading

Chat with Support