LetterDuck
Deliverability

SPF, DKIM, and DMARC: three records, one system

SPF says who may send, DKIM proves who signed, DMARC decides what happens when neither holds up. Treat them as one system or watch mail vanish.

Since November 2025, Gmail returns a permanent 550 error to mail that fails both SPF and DKIM, and Microsoft's consumer inboxes have rejected unauthenticated bulk mail since May 2025. Authentication stopped being a best practice and became the price of delivery. The three records involved are usually taught as a checklist. They work better understood as one system with three roles: SPF says who may send, DKIM proves who signed, and DMARC decides what happens when neither holds up for the domain your reader actually sees.

The problem all three exist to solve

The From header in an email is plain text. SMTP, the protocol mail servers speak to each other, checks it against nothing. Anyone can put billing@yourdomain.com in the From line of a message sent from anywhere on earth, and for the first few decades of email that message would simply arrive. Every phishing campaign that impersonates a bank works this way.

SPF, DKIM, and DMARC are three DNS records that give receiving servers a way to check the claim. Each answers one question, and none of them is sufficient alone, which is why our email deliverability handbook treats the trio as the floor of every send, not an optional hardening step.

RecordQuestion it answersWhere it livesStandard
SPFWhich servers may send mail for this domain?TXT record on the domainRFC 7208 (2014)
DKIMWas this exact message signed by the domain, and did it arrive unmodified?TXT record at selector._domainkeyRFC 6376 (2011)
DMARCDoes the passing domain match the visible From, and what should receivers do if not?TXT record at _dmarcRFC 7489 (2015)

SPF: who may claim the domain

SPF is a published list of sending servers. When mail arrives, the receiver looks up a TXT record on the sender's domain and checks whether the connecting IP address is on the list.

The subtlety: SPF does not check the From address you see in your mail client. It checks the envelope sender, also called the Return-Path, a hidden address used for bounce handling. Those two addresses are frequently different, and that gap matters enormously once we get to alignment.

A typical record is one line:

example.com.  TXT  "v=spf1 include:_spf.google.com ~all"

Translation: Google's servers may send for this domain, treat everyone else with suspicion. The full syntax (mechanisms, qualifiers, the 10-lookup limit that silently breaks records) gets its own reference in our SPF record guide.

DKIM: who signed the message

SPF authenticates the connection. DKIM authenticates the message itself. Your sending server computes a hash over the message body and selected headers, signs it with a private key, and stamps the result into a DKIM-Signature header. The receiver fetches the matching public key from your DNS, at an address like s1._domainkey.example.com, and verifies the signature.

Because the signature rides inside the message, DKIM keeps working when mail passes through intermediate servers. That single property makes it the sturdiest of the three, and the details (selectors, key length, what the signature actually covers) are in our DKIM explainer.

DMARC: who enforces

Without DMARC, SPF and DKIM are advisory. A receiver sees a failure and makes a private judgment call. DMARC is the domain owner publishing the judgment in advance:

_dmarc.example.com.  TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"

The p= tag is the policy: none (deliver anyway, just report), quarantine (spam folder), or reject (refuse outright). The rua= tag is where receivers send aggregate XML reports about every message claiming your domain, which is how you find senders you forgot about before you tighten the policy. The none-to-reject progression deserves a project plan of its own, and we wrote one in What is DMARC.

Alignment: the part most guides fumble

Here is the loophole that DMARC exists to close, and that most three-paragraph summaries never mention.

SPF checks the Return-Path domain. DKIM checks the d= domain named inside the signature. Neither is required to have anything to do with the From address your reader sees. So a phisher can send from their own domain, with flawless SPF and a valid DKIM signature for phisher-mail.net, while displaying yourbank.com in the From line. Both checks pass. The reader sees your bank.

DMARC adds the missing rule: at least one passing check must align with the From domain. SPF aligns when the Return-Path domain matches the From domain. DKIM aligns when the d= domain matches. In the default relaxed mode a subdomain counts (mail.example.com aligns with example.com); in strict mode the match must be exact.

One aligned pass is enough. That "one is enough" rule is not a technicality. It is the entire reason forwarded mail can survive, as we found out the hard way.

A worked example

Take example.com, hosted on Google Workspace, sending its newsletter through an ESP. Three TXT records make the whole system:

example.com.                    TXT  "v=spf1 include:_spf.google.com ~all"

google._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEF...IDAQAB"

_dmarc.example.com.             TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

Now trace one message from hello@example.com to a Gmail user. Gmail's server accepts the connection and runs the checks in order. SPF: the connecting IP belongs to Google's pool, which _spf.google.com includes, so SPF passes, and the Return-Path domain is example.com, so it aligns. DKIM: the message carries a signature with d=example.com and selector google; Gmail fetches google._domainkey.example.com, verifies the hash, pass, aligned. DMARC: at least one aligned pass exists, so the message passes DMARC, and the p=none policy would not have punished a failure anyway. The message is delivered, and once a day Gmail mails a summary of everything it saw to dmarc-reports@example.com.

Two passes is the healthy state. You need both because each one fails in situations the other survives.

Forwarding breaks SPF: we have the numbers

In June 2026 we were mirroring every inbound message on our domain to a Gmail archive using Cloudflare's message.forward(). No errors on our side, all green. Then we noticed mail was missing from the archive, quietly, with no bounce we could see. When we pulled the numbers, Gmail had been rejecting roughly 73% of everything we forwarded.

The mechanism is textbook. A forwarder re-sends someone else's message from its own IP address. That IP is not in the original sender's SPF record, so SPF fails on every single forwarded message, by design, with no workaround. The message can still pass DMARC through the other door: an intact, aligned DKIM signature travels with the message and verifies anywhere. But any message that arrived unsigned, or whose signature broke in transit, had nothing left. Under the sender's DMARC policy, Gmail refused it.

We stopped forwarding and switched the mirror to a Gmail API insert, which sidesteps SMTP entirely. The general lessons survive the specifics: SPF alone is fragile in the real world, DKIM is the only authentication that survives forwarding, and a DMARC policy is enforced silently, so the sender never sees the damage. If your setup relies on SPF passing everywhere, some of your mail is already failing somewhere.

Set them up in this order

The order matters less for DNS than for risk: you want signing and listing in place before any policy exists to punish their absence.

  1. DKIM first. Turn on signing at your mail host and ESP, publish the selector records they give you, and send a test to a Gmail address. Open it and use Show original to confirm DKIM: PASS.
  2. SPF second. One TXT record listing every service that sends for you. Keep it under 10 DNS lookups.
  3. DMARC at p=none with a rua address. This punishes nothing and starts the reports flowing.
  4. Read reports for two to four weeks. Find the printer, the CRM, the billing tool you forgot authenticates nothing.
  5. Tighten to p=quarantine, then p=reject, only when the reports show every legitimate source passing with alignment.

For where BIMI fits, and what to prioritize at each sending volume, the series overview is our email authentication guide. But the sequence above is the work. Three TXT records, one system, and the receivers stop guessing.