First, find where the email stopped
- 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.
- 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.
- 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.compublishes a DMARC policy ofp=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.
// 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=noneonly monitors. That’s the right place to start.
; 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:
| Requirement | All senders | Bulk senders |
|---|---|---|
| Authentication | SPF or DKIM | SPF and DKIM, plus DMARC (p=none is enough), with the From domain aligned |
| Spam rate | Below 0.3% | Below 0.3% |
| Other | Gmail also requires TLS, valid forward and reverse DNS for the sending server, and correctly formatted messages | One-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:
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.
<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.
- Gmail Help: Email sender guidelines
- Yahoo Sender Hub: Sender best practices
- Gmail Help: Trace an email with its full headers
- Gmail Help: Sender information (“via”)
- Google Workspace: Troubleshoot DKIM issues
- Google Workspace: Set up SPF
- Google Workspace: Gmail SMTP errors and codes
- RFC 7208: Sender Policy Framework (SPF)
- RFC 7489: DMARC
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.