Guides

Contact form emails going to spam or not arriving: fixes

Your form says “Thanks!”, and the email lands in spam or nowhere. Usually the From address is the problem, followed by missing DNS records. Here’s how to find out which one, and fix it.

Last updated November 2, 2026

First, find where the email stopped

  1. Never sent. The form submitted but your code or service logged an error, or your host blocked the SMTP port. Check your server logs or the service’s logs for an SMTP reply. If there’s a timeout, see SMTP connection timed out.
  2. Sent, then rejected. The sending mailbox received a bounce. The code in it (550 5.7.26, 554 5.7.1…) is explained in the SMTP error code reference.
  3. Delivered to spam. Search the spam folder for the subject line. The rest of this page is for you.

The most common mistake: sending “from” the visitor

Many form scripts put the visitor’s address in the From header, so the email seems to come from them. But your server isn’t allowed to send for gmail.com or yahoo.com. When a receiver checks the visitor’s domain, SPF and DKIM can’t pass for it, and DMARC fails.

  • yahoo.com publishes a DMARC policy of p=reject (we checked its DNS on November 2, 2026). Mail claiming to be from a Yahoo address that fails DMARC can be refused outright.
  • Google’s sender guidelines say “Don’t impersonate Gmail From: headers” and warn that Gmail will begin using a DMARC quarantine enforcement policy for them.

The fix: send from your own address and put the visitor in Reply-To. Hitting Reply still answers them.

js
// Wrong: the visitor's address in From. Your server isn't allowed to send for gmail.com,
// so SPF and DKIM can't pass for that domain and DMARC fails.
from: req.body.email,

// Right: your own address in From, the visitor in Reply-To.
from: '"Website" <hello@yourdomain.com>',
replyTo: req.body.email,

In PHPMailer: $mail->setFrom('hello@yourdomain.com') and $mail->addReplyTo($email, $name).

SPF, DKIM and DMARC for form owners

These are DNS records on the domain in your From address. Your email provider gives you the exact values.

  • SPF lists the servers allowed to send for your domain. Use one SPF record per domain: RFC 7208 says more than one is a permanent error.
  • DKIM signs each message. The public key lives in DNS under a selector your provider chooses.
  • DMARC tells receivers what to do when a message fails, and it requires the From domain to match (“align with”) a domain that passed SPF or DKIM. p=none only monitors. That’s the right place to start.
text
; SPF: which servers may send for yourdomain.com (one SPF record per domain)
yourdomain.com.         TXT  "v=spf1 include:_spf.google.com ~all"

; DKIM: a public key your provider gives you, under a selector it chooses
google._domainkey.yourdomain.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBg..."

; DMARC: what receivers should do when a message fails, and where to send reports
_dmarc.yourdomain.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"

The SPF line above is Google’s recommended record for a domain that sends only through Google Workspace. Other providers use their own include:.

What Gmail and Yahoo require

Both started enforcing sender requirements in February 2024. A contact form that sends a few messages a day falls under the rules for all senders:

RequirementAll sendersBulk senders
AuthenticationSPF or DKIMSPF and DKIM, plus DMARC (p=none is enough), with the From domain aligned
Spam rateBelow 0.3%Below 0.3%
OtherGmail also requires TLS, valid forward and reverse DNS for the sending server, and correctly formatted messagesOne-click unsubscribe for marketing mail. Yahoo also requires honoring unsubscribes within 2 days.

Gmail’s bulk threshold is 5,000 or more messages a day to personal Gmail accounts. When you send through your mailbox provider’s SMTP server, the provider handles TLS and reverse DNS. You handle the DNS records for your domain.

Check the headers

Send a test submission to a Gmail address, open it, click More (next to Reply), then Show original. Find the Authentication-Results header:

text
Authentication-Results: mx.google.com;
       dkim=pass header.i=@yourdomain.com;
       spf=pass smtp.mailfrom=hello@yourdomain.com;
       dmarc=pass header.from=yourdomain.com
  • spf=fail or softfail: your SPF record doesn’t include the server that sent it.
  • No dkim line, or dkim=fail: DKIM isn’t set up for this domain at your provider.
  • dmarc=fail: neither SPF nor DKIM passed for the From domain. Usually that’s the From-the-visitor mistake.
  • “via” next to the sender name: Gmail shows this when the sending domain doesn’t match the From domain.

Google’s Admin Toolbox Messageheader tool can analyse a pasted header.

Checklist

  • From is your own address, on your domain or your mailbox. Never the visitor’s.
  • The visitor’s email goes in Reply-To.
  • From matches the SMTP account you log in with, or an alias it’s verified for.
  • One SPF record that includes your provider.
  • DKIM turned on at your provider and published in DNS.
  • A DMARC record, starting with p=none.
  • Bots filtered out before they reach your inbox. See contact form spam protection.
  • A plain subject line such as “New message from yourdomain.com”, not the visitor’s text.

How FormSMTP handles this

Using FormSMTP? FormSMTP sends each submission through your own SMTP account from your project’s From address, and sets the visitor’s address (a field named email, or _replyto) as Reply-To. The visitor is never in From. The Deliverability panel in Settings checks SPF, DKIM (on common selectors, or the one you enter), DMARC and MX for your From domain. Start free.

html
<form action="https://app.formsmtp.com/api/v1/form/YOUR_FORM_KEY" method="POST">
  <label>Name <input name="name" required></label>
  <!-- A field named "email" becomes the Reply-To, so Reply answers the visitor -->
  <label>Email <input name="email" type="email" required></label>
  <label>Message <textarea name="message" rows="5" required></textarea></label>
  <input type="hidden" name="_subject" value="New message from yourdomain.com">
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
  <button type="submit">Send</button>
</form>

Setting up from scratch? Read how form SMTP works, use the Gmail guide, or pick a provider from free SMTP servers compared.

Sources

Checked on the vendors’ own pages on November 2, 2026.

FAQ

Why do my contact form emails go to spam?

Most often because the form sends “from” the visitor’s address, which fails DMARC for their domain. Send from your own address with the visitor as Reply-To, and publish SPF, DKIM and DMARC records for your domain.

Should the From address be the visitor’s email?

No. Put your own address in From and the visitor’s in Reply-To. You can still reply with one click, and the message passes authentication.

Do I need DMARC for a contact form?

Gmail and Yahoo require SPF or DKIM from all senders, and DMARC only from bulk senders. A DMARC record with p=none changes nothing about delivery but sends you reports on who is sending as your domain, so it’s worth adding.

How do I check if an email passed SPF and DKIM?

In Gmail, open the message, click More next to Reply, then Show original. The Authentication-Results header shows spf=, dkim= and dmarc= results.

My form shows “success” but no email arrives. What now?

Check spam first, then your sending mailbox for a bounce, then your server or service logs for an SMTP error. A timeout in the logs means the host blocks SMTP ports.

More guides

Get a Founding Pass

10,000 emails a month, free for your first year. Pass No. 0008 is next: 1,993 of 2,000 left, no card.