AutomationSetup

Troubleshooting guide

Contact form not sending email? Check each handoff

Do not start by changing random mail settings. First find the last place where you can prove the submission existed. A contact form crosses several independent systems, and each one leaves different evidence when it fails.

Important: the free check does not submit your form. It confirms only that an outside monitor can load and recognize the public lead path. Submission and email delivery require an authorized end-to-end test.

A success message is not a delivery receipt

Many forms display “Thanks” after the browser receives a response. That proves the page reached some success branch. It does not prove the server stored the lead, the mail provider accepted a notification, or the destination inbox received it. Treat the form as a chain of handoffs:

Browser → form handler → durable record → notification provider → destination inbox.

The fastest diagnosis is to test once with a unique marker, record the exact time, and move through that chain in order. Stop at the first missing receipt.

1. Make one identifiable test submission

Use an address you control and put a unique marker in the message, such as FORM-CHECK-2026-08-30-1430. Record the exact time, page URL, and what the browser displayed. Do not send ten identical tests: duplicates can trigger spam rules or rate limits and make the evidence harder to read.

If the submit button does nothing, the page shows a validation error, or the browser reports a network failure, stay at the browser-to-handler layer. Check required fields, the form action, front-end console errors, blocked scripts, CAPTCHA state, and the actual response to the submit request.

2. Read the submit response, not only the page message

Open the browser network panel and submit again. Find the request created by the form. Record its URL, status code, and response body. A 404 points at a missing or wrongly routed handler. A 401 or 403 points at an authorization, origin, WAF, or verification rule. A 429 is a rate limit. A 5xx means the server failed while handling the request.

A 200 response narrows the search but does not finish it. Read what the response claims, then look for the corresponding server-side record.

3. Find the durable submission record

Check the form plugin entry list, CRM, database, server log, or key-value record that should exist before an email is sent. Search for the unique marker and exact timestamp. If no record exists, the failure happened before persistence. If the record exists, the customer data reached the server and the next question is notification delivery.

If your form has no durable record at all, add one before relying on email. An inbox is a delivery destination, not a submission ledger. Without a stored record, a provider outage can erase the only copy of the lead.

4. Check the notification attempt and provider receipt

A useful submission record should say whether notification was pending, sent, or failed, when it was attempted, and which provider accepted it. Then inspect the provider log for the same timestamp and recipient. “Request accepted” and “message delivered” are separate states; preserve the provider message ID when one is returned.

If the application stored the lead but never attempted a notification, inspect the code path after persistence. If it attempted and failed, verify the API credential, sender, recipient, account status, quota, and provider response rather than changing the visible form.

5. Trace the final inbox handoff

If the provider accepted the message, check spam, quarantine, forwarding rules, filters, aliases, and the exact destination address. For Gmail and Google Workspace recipients, Google’s official contact-form delivery troubleshooting distinguishes the form from the system that sends its email and walks through sender and domain-authentication checks.

Test a second destination only after preserving the first result. If one provider receives the notification and another does not, the form handler is probably no longer the first place to investigate.

6. If the site is on Cloudflare Pages, verify the deployed function

A static form cannot run server-side delivery by itself. On Cloudflare Pages, the functions/ directory creates server-side routes through file-based routing; Cloudflare documents that model in its Pages Functions overview and routing reference. Confirm that the function lives at the project root, the deployed route matches the form action, and required storage or secret bindings exist in the production environment.

Test the production URL after deployment. A local emulator proves local behavior; it does not prove the production bundle contains the function or that production has the same bindings and credentials.

7. Re-test the whole path after the fix

Repeat the same marked submission. Require evidence at every handoff: browser response, stored record, notification attempt, provider receipt, and inbox arrival. Then document what changed. A fix is not complete because the page looks normal again; the customer’s message has to arrive.

Symptom-to-layer checklist

What you observeCheck next
Button does nothingRequired fields, client JavaScript, CAPTCHA, and the browser network request.
Submit request returns 404Form action, deployed handler route, and host redirects.
Page says success, but no stored record existsThe handler’s success branch and persistence call.
Stored record exists with notification failedProvider credential, sender, recipient, quota, and provider response.
Provider accepted it, but inbox is emptySpam, quarantine, forwarding, filters, and sender authentication.
Tests pass only sometimesRate limits, WAF rules, transient dependencies, and retry behavior.

Failures we have found in our own lead paths

This checklist comes from operating the same kind of path, not from treating every missing email as one generic SMTP problem. In our own deployed portfolio we have found:

  • An immutable cache URL that still pointed returning browsers at older form JavaScript after the source changed.
  • A handler that told the browser “success” before the notification attempt had finished, so the customer saw success while the operator could receive nothing.
  • A notification-failure branch that retained repeated submissions without recording the normal rate-limit gate.

Those failures lived at different handoffs and needed different fixes. That is why the paid monitor combines endpoint probes with authorized browser submissions and confirmation at the destination. A page-only uptime check cannot prove email delivery.

Published and reviewed 2026-08-30.