← Back to blog

Why your form notification emails land in spam

The Formward TeamFormward, Stockholm7 min read

A form backend has one job that matters more than the rest: when somebody fills in your form, you find out. So the failure that hurts most is the quiet one. The submission is stored, the dashboard shows it, the delivery log says the email was accepted, and yet nothing appears in your inbox. Days later you find it sitting in a junk folder you never open. We spent a while recently pulling this apart on our own infrastructure, and the mechanism is worth explaining, because the intuitive diagnosis is usually wrong.

The instinct is to blame domain reputation or a missing DNS record. Sometimes that is right, and it is the first thing to rule out. But form notifications get filtered at a higher rate than ordinary business mail even when the authentication is perfect, and the reason is structural. A notification email is an unusual shape. It is sent by one party (your form backend), it claims to come from your domain, it is addressed to you, and it usually carries a stranger's email address in the Reply-To header so that hitting reply talks to the person who filled in the form. That combination looks, to a filter that has never seen your setup before, quite a lot like a phishing attempt.

This is worth sitting with, because it explains the whole category. Consider what a spoofing attack looks like from a filter's perspective: a message that appears to come from a domain, arrives via a relay that is not that domain's usual mail server, and asks you to reply to somewhere else entirely. Now consider a legitimate form notification: it appears to come from your form backend's sending domain, it arrives via that backend's email provider, and its Reply-To points at whichever visitor filled in the form. The signals overlap almost exactly. The difference is intent, and intent is precisely what a filter cannot see.

The trap that catches people hardest is notifying an address on the same domain as the sending address. If notifications appear to come from something at your-company.com and you send them to team@your-company.com, some filters treat an external Reply-To on an apparently internal message as a strong spoofing signal, because that is the classic shape of a business email compromise attempt. Rspamd, which sits in front of a great many mail servers, has a dedicated rule for exactly this pattern, and it is weighted heavily enough to push an otherwise clean message straight past the spam threshold on its own. We tripped this ourselves while testing, sending notifications from our own domain to a mailbox on our own domain, and the message was filed as junk despite passing every authentication check.

So before you start rewriting DNS records, work out which problem you actually have. Open the message that got filtered, view its full source, and read two things. First, the authentication results header, which tells you whether SPF, DKIM and DMARC passed. Second, whatever spam report your server attached, which on most modern setups lists the individual rules that fired and what each one scored. That second header is the one people skip, and it is the one that tells you the answer. A message can score high for half a dozen reasons that have nothing to do with your domain being untrusted.

If the authentication results show a failure, fix that first, because nothing else matters until it passes. You need three records. SPF lists which servers may send on behalf of your domain, and it must include whichever provider your form backend uses. DKIM publishes a public key so the receiving server can verify a cryptographic signature on each message, which proves the content was not altered in transit and genuinely came from an authorised sender. DMARC tells receivers what to do when the first two disagree, and it is what turns SPF and DKIM from advisory into enforced. Publish all three, and confirm they actually pass on a real delivered message rather than assuming the DNS record being present is the same as it working.

If authentication passes and the message still gets filtered, you are dealing with content and shape rather than trust, and there are a few practical moves. Send notifications to an address on a different domain from the sending domain, which sidesteps the internal-spoofing heuristic entirely. If you cannot, add the sending address to your allow list, which is a two-minute change on most mail servers and permanently ends the problem for that mailbox. Keep the notification itself plain and text-first, because heavy HTML with many hidden elements and tracking pixels scores badly. And be aware that the reply-to-the-submitter convenience, useful as it is, carries a real deliverability cost, which is why some teams prefer notifications that come from and reply to their own domain, with the submitter's address in the body.

There is a second failure mode hiding behind the first, and it is the one that actually loses business. Once a message has been filed as junk, everything downstream that reads only your inbox is blind to it. If you forward form notifications into a shared mailbox, a ticketing system, or an automation, the junk folder is usually invisible to all of them. The email was delivered, your server accepted it, your logs are clean, and yet no human and no system will ever see it. This is worse than a bounce. A bounce is loud and tells you something failed; a junked message is silent and looks exactly like nothing having happened.

We hit this in our own support inbox, which is a slightly embarrassing thing to admit publicly and a useful thing to have found. Our support mail is polled over IMAP and shown to our team in one place, and the poller read only the inbox. Any message our own server's filter judged to be spam was accepted, stored on disk, and never surfaced to a human. We have since changed it to read the junk folder as well, marking anything it finds there as suspected spam so it appears in a separate view rather than cluttering the main queue, where a human can rescue a false positive in one click. If you run anything that reads a mailbox programmatically, go and check whether it reads the junk folder too, because the odds are it does not.

The practical routine that comes out of all this is short. When you set up a form, send yourself a real submission and confirm the notification arrives in the inbox rather than assuming it did. Check the junk folder specifically, because a message sitting there is the single most common cause of the notifications are not working. Allow-list the sending address on the mailbox that receives your notifications. And if you have a compliance or IT team, ask them whether anything filters mail before it reaches the mailbox you are watching, because a rule written years ago for a different reason will happily eat your form submissions today.

None of this is unique to any one provider, and it is not a problem you solve once and forget. Filters are updated continuously, thresholds move, and a message shape that has been fine for a year can start scoring differently after a rule change upstream. That is the argument for treating delivery as something you verify rather than assume: keep the dashboard as the source of truth for what was actually submitted, treat email as a notification channel rather than the record itself, and check the junk folder before you conclude that nothing arrived.

About the author

The Formward Team builds privacy-first form infrastructure in Stockholm. Read about our security and privacy practices. Our approach follows the principles set out by the European Data Protection Board at edpb.europa.eu.

Why your form notification emails land in spam | Formward