WPForms goes silent after a security plugin update
This is the exact class of bug the "Emergency Form Fix" service targets: the form looks fine to every visitor, and there is no error anywhere in wp-admin โ but the business hasn't received a single lead in days.
Step 1
Reproduce before touching anything
Before changing a single setting, submit a real test entry through the live form exactly as a visitor would โ same browser, no admin session, no ad blockers disabled. This confirms the failure is real (not, say, a lead landing in spam) and captures the exact conditions to compare against after the fix.
Result: the success message displayed normally. No email arrived at the site's admin address within 10 minutes. The WPForms entry itself, however, did save correctly in wp-admin โ WPForms โ Entries โ which immediately narrows the bug from "form is broken" to "form saves the entry but the notification email never sends."
Step 2
Isolate: plugin, mail transport, or hook conflict?
Three usual suspects for this exact pattern, checked in order of likelihood and cost to check:
| Check | Finding |
|---|---|
| WP debug log during test submission | No PHP errors or warnings logged |
| Recent plugin update history (Tools โ Site Health / hosting panel) | Security plugin updated 6 days ago โ matches the reported timeline |
| WPForms โ Settings โ Notifications | Notification is enabled and correctly addressed |
Test wp_mail() directly via WP-CLI (wp eval 'wp_mail("test@x.com","t","b");') | Also silently fails โ confirms this is a mail transport problem, not a WPForms bug |
mail() function
from a subset of server processes as a hardening measure, without
surfacing any warning in wp-admin. WPForms was never broken โ the entire
site's outbound mail was broken, and WPForms was just the first place
anyone noticed because it's customer-facing.
Step 3
Fix the actual cause, then verify
The fix here was to reconfigure outbound mail to go through an
authenticated SMTP connection instead of PHP's mail(), so it's
no longer subject to that hardening rule (and is more deliverable in
general โ fewer landing in spam). After the change, the same live-form test
from Step 1 was repeated and the notification arrived within seconds.
This is also why a fix isn't called done here until a real test lead is confirmed delivered โ a config change that "should" work isn't the same as watching the email actually land.
Step 4
Wire in a alert that survives the next update
The underlying risk doesn't go away just because this specific cause is fixed โ a future plugin or hosting change could break mail delivery again, silently, the same way. The fix for that is a second, independent notification path that doesn't depend on the form plugin's own mail handling: a Slack webhook fired directly from the form's submit hook, plus a backup email sent through a separate code path.
// wp-content/mu-plugins/wp-lead-alerts.php (excerpt)
// mu-plugins can't be deactivated by a future plugin update โ the
// alert layer stays in place even if the form plugin changes again.
add_action( 'wpforms_process_complete', function ( $fields, $entry, $form_data ) {
$summary = "New lead via WPForms (\"{$form_data['settings']['form_title']}\")\n"
. wpla_format_fields( wp_list_pluck( $fields, 'value' ) );
wpla_notify_slack( $summary ); // independent Slack webhook
wpla_notify_backup_email( 'New lead', $summary ); // separate wp_mail() call
}, 10, 3 );
// Contact Form 7 gets the same treatment, but also alerts on FAILURE โ
// this is the line that would have caught the bug above the moment it happened:
add_action( 'wpcf7_mail_failed', function ( $contact_form ) {
$msg = "Contact Form 7 mail FAILED for \"{$contact_form->title()}\" โ check mail config now.";
wpla_notify_slack( "๐จ $msg" );
wpla_notify_backup_email( 'ALERT: form mail failed', $msg );
} );
The full file โ including Gravity Forms and WooCommerce support โ is what ships with the Lead Alert Setup add-on. It's a single mu-plugin file, no database changes, no third-party service required beyond an optional free Slack incoming webhook.
Result
| Before | After |
|---|---|
| Leads silently discarded for 6+ days | Test lead confirmed delivered within seconds |
| Single point of failure (site's own mail()) | Two independent alert paths (SMTP email + Slack) |
| No warning if it breaks again | Immediate Slack ping on any future mail failure |