mildnode

/ Monitoring

Your contact form is broken and nobody is going to tell you

A form that fails loudly gets fixed the same day. The expensive kind shows the visitor a thank-you message and then drops the enquiry, and the only signal is that the phone is quieter than usual — which looks exactly like a slow month.

/6 min read

Somebody who fills in your contact form and hears nothing does not email you to ask whether the form worked. They assume you are not interested, and they contact somebody else. There is no complaint, no error, no bounce — which is why this particular failure routinely runs for months.

It is also one of the most common failures on a small business website, because a contact form has an unusual number of independent parts and a visible success message that is often shown before any of them have actually succeeded.

Where the enquiry actually goes missing

Roughly in order of how often each one turns up:

  • The form sends mail as the visitor. It puts the visitor's address in the From header, which means your domain is sending mail claiming to be from someone else's. SPF and DMARC exist precisely to stop that, so the message is filtered or rejected — correctly.
  • The destination address no longer exists. Somebody left, the mailbox was closed, and the form still points at it. Depending on the provider this bounces to nowhere or is accepted and discarded.
  • The notification lands in the destination's own spam folder. Especially likely for the reason above, and especially invisible, because nobody checks the junk folder of a shared inbox.
  • The mail plugin's credentials expired. A password changed, an app password was revoked, an API key rotated. The site keeps showing the success message because sending is attempted after the response is sent.
  • The anti-spam check silently rejects real people. A captcha failing to load, a honeypot field being autofilled by a password manager, or a score threshold set too aggressively.
  • The submission never leaves the browser. A JavaScript error on the page stops the handler running, so the button does nothing — or, worse, the page shows the success state locally and never posts anything.

Notice what those have in common: the page looks correct in every single case. It returns a normal status code, renders the form, accepts input and confirms receipt. Nothing an uptime monitor looks at changes.

Why testing it yourself proves less than you think

The standard check is to fill in your own form and see whether the mail arrives. It is worth doing and it is not sufficient, for three reasons.

You are a different sender. Your address is probably on an allowlist at your own mail provider, or in your own contacts, which means your test message can bypass a filter that a stranger's would not. A test that passes for you and fails for everybody else is the normal outcome of this failure mode.

You also test from the same browser, usually logged in, often with a session or a cookie that a first-time visitor does not have. And you test once, after making a change — not at three in the morning two months later when a plugin updated itself.

If you only do one thing from this piece: send a test from an address on a different provider to your own — a personal Gmail or Outlook, not another address on your business domain — and check the junk folder as well as the inbox.

The five-minute audit

  1. Submit the form as a stranger would: a private window, logged out, from your phone on mobile data rather than the office network.
  2. Confirm the notification arrives, and note which folder it arrives in.
  3. Open the notification and look at the From address. If it is the visitor's address rather than one on your own domain, that is the problem, and the fix is to send from your own address with the visitor's in Reply-To.
  4. Check that the destination mailbox is one somebody actually opens — not an alias forwarding to a closed account.
  5. If the form promises the visitor a confirmation email, check that too. It is a separate send and it fails separately.
  6. Submit a second time with deliberately awkward input: an apostrophe in the name, a long message, a + in the address. Validation that rejects real people is a quieter version of the same loss.

The From header in step three is worth labouring, because it is the most common cause and the least intuitive fix. Your form should send from something like website@yourdomain.com, with the visitor's address set as Reply-To. You still hit reply and it still goes to them — but the message is now genuinely from your domain, which is the only version that survives SPF and DMARC.

Making it somebody's job rather than somebody's memory

An audit catches today's breakage. The problem is that forms break later, on days nobody is auditing — a plugin updates, a certificate on the mail host renews wrongly, a provider tightens a filter.

A calendar reminder to test the form monthly genuinely works and costs nothing. It will also be skipped by the third month, which is the honest reason automated checks exist.

If you automate it, the useful check submits the form the way a visitor does — in a real browser, with the real scripts running — and asserts on the confirmation the visitor would see. Asking whether the page loads tells you nothing here, for all the reasons in why uptime checks miss a broken checkout.

Two practical cautions if you do. Submit to a dedicated test destination rather than your main enquiry inbox, or you will train yourself to ignore the one mailbox that matters. And confirming that mail arrived is a separate problem from confirming the form submitted — a browser check proves the second, and only reading a mailbox proves the first. Most of the value is in the second; most of the remaining risk is in the first.

If you sell by enquiry, this is your checkout

Businesses that take payment online know to watch the checkout. Businesses that quote, book or consult often watch nothing, because there is no obvious transaction to monitor — and their contact form is carrying the entire revenue of the company.

The arithmetic is the same. Work out what one enquiry is worth and how many you get in a week, and you have the cost of a day of silence. For most small businesses that number makes any amount of checking look cheap.

/ Questions

Asked about this

Why do my form notifications go to spam?

Usually because the form sends with the visitor's address in the From header, so your server is sending mail claiming to be from a domain it is not authorised for. Send from your own address and put the visitor's in Reply-To instead.

The form says 'thank you' — doesn't that mean it worked?

Not necessarily. Many forms show the success state as soon as the submission is accepted, before or independently of the mail actually being sent. The confirmation tells you the page handled the click, not that anyone received anything.

How often should I test it?

Monthly by hand is a reasonable floor, and the realistic answer is that it gets skipped. If enquiries are how you get work, this is the thing worth checking automatically, the same way a shop watches its checkout.

Should an automated check send to my real inbox?

No. Use a dedicated address, or you will have taught yourself to ignore submissions in the one mailbox where a real enquiry arrives. The point is to detect failure, not to add noise to the thing being protected.

/ Journey Monitoring

A contact form is a journey like any other: you fill it in once while we record the steps, and from then on we repeat exactly those steps and tell you only when the confirmation stops appearing — confirmed twice, from two places, before anyone is woken.