Elementor Pro forms break in subtle ways. The submit button works, the success message appears, and yet the email never arrives or — worse — submissions look “empty” in your admin. I just spent a day fixing this exact problem on a live client portfolio: the form rendered five fields, the user filled them, the success toast fired, and the backend log captured a single key called Message with an empty value. Every other field was silently dropped.
If you’ve ever stared at a “successful” Elementor form submission that contained nothing, this guide is for you. These are the 12 fixes I run through, in order, when an Elementor Pro form misbehaves in 2026. Most take under five minutes once you know where to look.
Fix #1: Add a custom_id to every form field
This is the bug that catches the most people. In the Elementor editor, every field has an Advanced > ID property called Custom ID. If you leave it blank, Elementor renders every input on the page with the same HTML name — form_fields[] with no key. When PHP receives the POST, it collapses all of those into a single array, and only the last value survives.
Open every field in your form and set a unique Custom ID like name, email, project_type, budget, message. Save the form. Now each input gets its own name attribute (form_fields[name], form_fields[email]) and PHP can read them all.
Fix #2: Check that Elementor Pro is actually licensed and active
The free Elementor plugin includes a basic form widget — but the real Form widget that triggers elementor_pro/forms/new_record ships only with Pro. If your Pro license lapsed or the activation broke, the widget reverts to a stub. Go to Elementor > License and reactivate. If your license is on the wrong site, deactivate from the other site first.
Fix #3: Run a server-side log of elementor_pro/forms/new_record
Before you debug anything else, prove the hook is firing. Drop this in a snippet plugin and submit your form:
add_action( 'elementor_pro/forms/new_record', function( $record, $handler ) {
$fields = $record->get( 'fields' );
error_log( 'ELEMENTOR FORM FIRED: ' . wp_json_encode( $fields ) );
}, 5, 2 );
Tail /wp-content/debug.log. If you see your fields, the form works and your problem is downstream (SMTP, integration, redirect). If nothing logs, the form isn’t reaching the action — usually a JavaScript or AJAX issue.
Fix #4: Disable conflicting JS optimizers
LiteSpeed Cache, WP Rocket, Autoptimize, and Perfmatters all defer or combine JavaScript by default. When they combine Elementor’s frontend.min.js with random vendor scripts, the form’s AJAX submit handler breaks silently. Test by temporarily turning off JS combination and JS deferral, then resubmitting. If it works, exclude elementor from optimization.
Fix #5: Verify the form’s reCAPTCHA isn’t blocking submission
If you added Google reCAPTCHA v3 and the score threshold is too aggressive (above 0.7), legitimate users get silently rejected. The success message never fires; the form just hangs. Lower the threshold to 0.4 or remove the captcha to test. For most freelance sites, a honeypot field beats reCAPTCHA — friendlier and zero false positives.
Fix #6: Check that your hosting allows mail()
Many managed hosts (Hostinger, SiteGround, Cloudways) disable PHP’s mail() function. Elementor’s email action calls wp_mail() which falls back to mail(). If it’s blocked, the submission still records but no email goes out. Install WP Mail SMTP and route through SendGrid, Brevo, Postmark, or Gmail. Send a test from WP Mail SMTP > Tools > Email Test before retesting your form.
Fix #7: Read the form’s data-settings attribute in the rendered HTML
Right-click the form, Inspect, find the <form> element. The data-settings attribute is a JSON object showing every option the JS handler will use. Confirm action_after_submit includes email (or whatever integration you expected). If it’s missing, the form was saved without an action — open the form in Elementor and add the email step under Actions After Submit.
Fix #8: Sanity-check the nonce
Open the page source and search for "nonce":". Elementor injects this into the JS config. If the nonce is missing or your page is cached as static HTML by Cloudflare, the AJAX submit returns a 403 and the form fails silently. Exclude logged-out form pages from full-page caching, or use Cloudflare’s “Bypass Cache on Cookie” with an Elementor-specific cookie.
Fix #9: Watch the network tab
Open DevTools, go to Network, submit the form, look for the POST to /wp-admin/admin-ajax.php with action elementor_pro_forms_send_form. Inspect the response. Common bad responses:
- 403 — nonce or capability problem (see fix #8)
- 500 — a PHP fatal during action processing; check
debug.log - 200 with
{"success":false}— validation failed or required field empty (look at thedata.errorsarray) - 200 with
{"success":true}but no fields in your log — fix #1 again
Fix #10: Disable browser autofill conflicts
Chrome’s autofill sometimes injects values into hidden honeypot fields, triggering Elementor’s spam protection. The form silently rejects the submission. Add autocomplete="new-password" on the honeypot field or rename it to something Chrome won’t recognize (avoid name, email, phone as honeypot IDs).
Fix #11: Check for plugin conflicts
Translation plugins (WPML, Polylang) and form security plugins (CAPTCHA 4WP, Anti-Spam by CleanTalk) hook into Elementor form processing and can drop submissions. Deactivate them one by one, retest, and reactivate. Cache plugins are also frequent culprits — purge cache after every test.
Fix #12: Rebuild the form fresh in a duplicated section
Sometimes the form widget’s stored settings get corrupted from years of editing — old field IDs that no longer exist, orphaned action references, mismatched field_columns values. If nothing else works, duplicate the section in Elementor, delete the old form, and rebuild it widget-by-widget. Twenty minutes of clean rebuild saves hours of detective work.
Bonus: Log every submission to a file you can actually read
The Elementor “Submissions” feature in Pro is decent, but if you want a flat-text audit trail (great for handing leads to a VA or grepping for a specific email), drop a logger like this:
add_action( 'elementor_pro/forms/new_record', function( $record ) {
$fields = $record->get( 'fields' );
$row = [];
foreach ( $fields as $id => $f ) {
$label = $f['title'] ?: $id;
$row[ $label ] = $f['value'] ?? '';
}
file_put_contents(
WP_CONTENT_DIR . '/uploads/form-leads.log',
sprintf( "[%s] %sn", date( 'Y-m-d H:i:s' ),
wp_json_encode( $row, JSON_UNESCAPED_UNICODE ) ),
FILE_APPEND | LOCK_EX
);
}, 10, 1 );
Every submission lands as one JSON line you can tail -f in real time. It’s saved me from missing leads more than once when an SMTP integration silently dropped emails for three days.
When to stop debugging and ship a custom form
If you’ve worked through these 12 fixes and the form still misbehaves, the cost-benefit tips toward a custom HTML form posting to a REST endpoint or a webhook (n8n, Make, Zapier). Elementor Pro forms are great for 80% of contact use cases, but if your form needs conditional logic across many fields, multi-step UX with persistence, or third-party validation (address autocomplete, VAT number lookup), a custom build is faster than fighting the widget.
I’ve built dozens of these for WordPress clients, and the pattern is consistent — clean HTML, a single REST endpoint, server-side validation, and a webhook to whatever CRM the client uses. If you want a look at how I structure them, the case studies walk through a few real builds. Or just drop me a line and I’ll audit your form for free.
Quick checklist for next time a form breaks
- Every field has a unique Custom ID
- Elementor Pro license is active
- Server log catches the
new_recordhook - WP Mail SMTP is configured and the test email arrived
- JavaScript optimizers exclude Elementor scripts
- The page isn’t being served as static HTML by your CDN
- Network tab shows a clean 200 with
success:true - Logged submissions are landing where you expect them
Run through that list before you spend three hours debugging — most form problems disappear in the first three checks.





