SPF, DKIM, and DMARC Explained: Why Your Email Lands in Spam
· by Andergrove Software
When your email lands in spam — or bounces outright — the cause is usually not the message. It is one of three DNS records: SPF, DKIM, or DMARC. Email’s underlying protocol lets any server claim to be any sender, so the world’s mailbox providers now demand proof, and these three records are how a domain provides it. Since Gmail and Yahoo tightened their sender requirements, they are no longer optional for anyone who sends real volume. Here is what each record actually checks, how they interlock, and the handful of misconfigurations behind most deliverability pain.
Email’s original problem: the From address is just text
SMTP, the protocol that moves email, was designed in 1982 for a network of institutions that trusted each other. Nothing in it verifies the sender: the From address is a free-text field, and any server can put any domain in it. That is all a basic phishing email is — a message that says it is from your bank, sent by a server that has nothing to do with your bank.
It gets slightly worse: every email actually has two from addresses. The envelope from (also called the Return-Path) is what the sending server announces during delivery and where bounces go; the header From is what the recipient sees in their mail client. They are set independently and often differ legitimately — a newsletter service sends with its own envelope domain on your behalf. Spoofers exploit exactly that gap, which will matter again when we get to DMARC.
SPF, DKIM and DMARC are the retrofitted fix. Each is published as a DNS TXT record on the sending domain, which means they are public — you can look up any domain’s records right now and see how, say, your own company authenticates its mail.
SPF: which servers may send for your domain
SPF (Sender Policy Framework) is an allowlist of sending servers. It lives in a TXT record at the domain root and reads like this:
v=spf1 include:_spf.google.com include:sendgrid.net -all
Translation: “Google’s servers and SendGrid’s servers may send mail for this domain; reject everything else.” When a message arrives, the receiving server checks whether the connecting IP address is covered by the list.
Three details cause most SPF trouble. First, the record may trigger at most 10 DNS lookups — each include: counts, and includes nest, so a domain using five or six sending services quietly blows the limit and SPF starts returning errors. Second, the final qualifier matters: -all (hardfail) tells receivers to reject unlisted servers, while ~all (softfail) merely suggests suspicion — fine while testing, weak as a permanent setting. Third, and least obvious: SPF checks the envelope from, not the header From the user sees. A spoofer can pass SPF for their own domain while displaying yours. SPF alone was never enough — that is not a flaw you can configure away, it is why DMARC exists.
SPF also breaks on forwarding: when a message is forwarded, the forwarding server’s IP is not on the original domain’s list. That failure mode is one of the main reasons the second mechanism exists.
DKIM: a signature that travels with the message
DKIM (DomainKeys Identified Mail) takes a different approach: instead of vouching for servers, it signs the message itself. The sending server computes a hash of the message body and selected headers (see SHA-256 explained — that is the hash doing the work here), signs it with a private key, and attaches the result as a DKIM-Signature header. The matching public key is published in DNS at selector._domainkey.yourdomain.com, so any receiver can verify that the message really was signed by the domain and has not been altered since.
The selector is just a label (google, s1, k2…) that lets one domain publish several keys — one per sending service, rotated independently. If you use Google Workspace plus a marketing platform, each signs with its own selector, and both keys sit in your DNS.
Because the signature rides inside the message, DKIM survives forwarding where SPF breaks. Its weakness is the mirror image: anything that modifies the message in transit — most classically a mailing list appending a footer — changes the body hash and invalidates the signature. The idea is the same one behind webhook signature verification: a signature proves both who sent the data and that nobody touched it on the way.
DMARC: the policy that ties them together
Here is the gap the first two leave open: SPF and DKIM each verify a domain — but not necessarily the domain in the From line the recipient reads. A phishing message can pass SPF for attacker.com in the envelope and display yourbank.com in the header, and both checks technically succeed.
DMARC closes the loop with one rule and one instruction. The rule is alignment: the message only passes DMARC if SPF or DKIM passes for the same domain shown in the header From. The instruction is policy — a TXT record at _dmarc.yourdomain.com telling receivers what to do with mail that fails:
v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com
p=none means “deliver anyway, just report it to me”; p=quarantine means “send it to spam”; p=reject means “refuse it.” The rua address receives aggregate reports from mailbox providers showing exactly who is sending as your domain and whether they pass — which is how you discover the forgotten billing system that sends unauthenticated invoices before you turn enforcement on.
The standard rollout is a ratchet: publish p=none, read the reports for a few weeks, fix every legitimate sender the reports expose, then step up to quarantine and finally reject. A domain that stops at p=none forever has documentation, not protection — spoofed mail still gets delivered.
Passing all three still doesn’t guarantee the inbox
Authentication is the entry ticket, not the seat. SPF, DKIM and DMARC prove the mail is really from you; they say nothing about whether anyone wants it. Filtering after authentication runs on reputation — of your sending IPs and your domain, built from complaint rates, bounce rates, spam-trap hits and how often recipients actually open your mail. A fully authenticated domain that buys a list and blasts it will land in spam anyway, with impeccable credentials.
The reason authentication moved from best practice to baseline is that the big providers made it mandatory: since 2024, Gmail and Yahoo require bulk senders to pass SPF and DKIM, publish a DMARC policy, and keep spam complaints low — and reject mail from domains that don’t. If deliverability suddenly cratered for a domain you manage, this checklist is the first place to look.
Check your domain in thirty seconds
All three records are public DNS, so auditing a domain takes one lookup. Our email auth checker fetches a domain’s SPF, DKIM and DMARC records and lints them in plain English: it counts SPF DNS lookups against the limit of 10, flags a permanent ~all, finds DKIM selectors, and tells you whether your DMARC policy actually enforces anything. It runs in your browser over DNS-over-HTTPS — only the domain name is sent, nothing else.
What good looks like: one SPF record (two is an automatic error) ending in -all and under the lookup limit; a DKIM key for every service that sends as you; and a DMARC record that has ratcheted past p=none. Check your own domain first — then check the domain of the last “urgent invoice” that made it to your inbox, and see how it got there.