Guide · 11 min read

SPF, DKIM and DMARC, Explained Without the Jargon

Three DNS records, three different jobs. What SPF, DKIM and DMARC each check, why a message can pass SPF and still fail DMARC, and what to publish first.

YeyMail Team ·

You bought a domain, pointed its mail somewhere, and the setup page handed you three lines of DNS text. One begins `v=spf1`. One is a long unbroken string published under a name containing `_domainkey`. One begins `v=DMARC1`. The instructions told you to paste them into your registrar's control panel and save. They did not tell you what any of them were, and nothing on the page suggested it mattered.

It matters, because the three fail in different ways and you will eventually have to work out which one has gone wrong. All three exist to patch the same hole. The protocol that carries mail across the internet was never built to check that a sender is entitled to the name in the From line, as Microsoft's own authentication documentation says plainly. Anyone running a mail server can put your domain there. SPF, DKIM and DMARC are the retrofit.

The short version: SPF is about which servers may send, DKIM is about whether the message arrived unaltered, and DMARC is the only one of the three that concerns itself with the address your recipient actually reads. Here is what each really checks, and why forwarding breaks one of them and not the others.

SPF authorises servers, not people

SPF is a list, published as a TXT record on your domain, of the machines allowed to send mail using that domain. RFC 7208 frames it as a way for the administrators of a domain to explicitly authorise the hosts permitted to use their domain names. A receiving server sees the IP address that connected to it, fetches your record, walks through its mechanisms, and decides whether that address is on the list.

The mechanisms are the parts you paste. `ip4:` and `ip6:` for literal addresses, `a` and `mx` for whatever your domain's own records point at, and `include:` to pull in another domain's list, which is how a hosted mail provider or a mailing platform gets covered. The record ends with an `all` mechanism carrying a qualifier: `-all` for a hard fail, `~all` for a soft fail, `?all` for neutral. RFC 7208 defines seven possible outcomes in total: none, neutral, pass, fail, softfail, temperror and permerror.

There is a limit that catches people out. RFC 7208 requires an implementation to stop after ten terms that cause DNS queries, counting `include`, `a`, `mx`, `ptr`, `exists` and `redirect`, and to return permerror beyond that. Every supplier you add consumes at least one, and some includes expand into more inside. A record that grew one tool at a time can quietly stop working.

The address SPF checks is not the one you see

This is the most misunderstood thing about SPF, and it explains most of the confusion that follows. An SMTP conversation carries two different sender addresses. The envelope sender is given in the `MAIL FROM` command, before any of the message itself is transmitted, and is usually recorded in the `Return-Path` header. It is where bounces go. The From header is part of the message content, and it is the only one your mail client displays.

SPF checks the envelope. RFC 7208 evaluates the RFC5321.MailFrom identity, recommends that verifiers separately check the HELO identity as well, and says that checking any other identity against an SPF version 1 record is not recommended without the publishing domain's explicit approval. The From header is a different identity. SPF has no opinion about it.

The consequence is uncomfortable. Someone can register a domain of their own, publish a correct SPF record for it, send from a server that record authorises, and put your address in the From line. SPF passes. Microsoft's documentation describes exactly this sequence as a way to send mail that passes SPF while displaying a domain the sender does not control. The recipient never sees the envelope, so nothing in front of them contradicts the forgery.

DKIM signs the message itself

DKIM takes a different approach. Your outgoing server computes a hash of the message body and of a chosen list of header fields, signs that with a private key, and inserts the result as a `DKIM-Signature` header. RFC 6376 specifies the tags it carries, including `d` for the signing domain, `s` for the selector, `h` for the headers that were signed, `bh` for the body hash, `b` for the signature itself, and `c` for canonicalisation.

The public half of the key lives in DNS. Given a signature with `d=example.com` and `s=foo.bar`, RFC 6376 says the verifier queries `foo.bar._domainkey.example.com`. The selector is what lets a domain hold several keys at once, which is how rotation happens without an outage, and how a provider can sign on your behalf under a name you publish.

Because the signature covers the message rather than the connection, it survives being passed along. RFC 6376 notes that transit is normally through relays that make no substantive change and therefore preserve the signature. The word doing the work there is normally. Canonicalisation sets the tolerance: `simple` permits almost no modification, `relaxed` absorbs common changes such as whitespace and rewrapped header lines. RFC 7960 records the classic offenders, a mailing list that prepends a tag to the subject or appends a footer to the body.

DMARC ties both of them to the From line

SPF authenticates a domain in the envelope. DKIM authenticates a domain in a signature. Neither is required to have any relationship to the domain your recipient reads. DMARC's contribution is to insist that one of them does, and RFC 9989 gives that requirement a name: Identifier Alignment. Relaxed alignment holds when the Author Domain has the same Organizational Domain as an authenticated identifier; strict alignment requires the two to be identical.

Alignment comes in two strictnesses, set by the `aspf` and `adkim` tags. Relaxed, the default, requires the organisational domains to match, so a From address at contoso.com aligns with an envelope at bounces.contoso.com. Strict requires the fully qualified names to be identical, and the same pair fails. A message passes DMARC if at least one of the two checks produces a pass on an aligned identifier, and fails only when both fail.

That is why an otherwise baffling result is so common. A marketing platform sends on your behalf using its own bounce domain in the envelope. SPF passes, for the platform's domain. Your From address is your own domain. The two do not align, so SPF contributes nothing to DMARC, and unless the platform also signs with `d=` set to your domain, DMARC fails on a message that passed SPF perfectly. Microsoft's troubleshooting guidance lists this as the classic alignment problem.

The record is a TXT record at `_dmarc` on your domain. `p=` carries the policy, `sp=` overrides it for subdomains that exist, `np=` covers subdomains that do not, `rua=` names an address for aggregate reports and `ruf=` for per-failure reports. RFC 9989, which replaced RFC 7489 in May 2026, dropped the old `pct=` sampling tag and tells receivers to ignore it where it still appears. Subdomains inherit the parent's DMARC record unless they publish their own, which is not true of SPF or DKIM.

RecordWhat it authenticatesWhere it livesWhat breaks it
SPFThe connecting IP, against the envelope senderTXT on the domainForwarding, an unlisted new sender, over ten DNS lookups
DKIMThe body and signed headers, against the `d=` domainTXT at `selector._domainkey`Anything that edits the signed parts in transit
DMARCAlignment with the visible From domainTXT at `_dmarc`SPF and DKIM both failing or both unaligned

Forwarding is where SPF gives up

If you forward mail from your domain to a mailbox elsewhere, this section is the one that concerns you. SPF is evaluated against the address of the server that made the connection. RFC 7208 covers this under mediators: when a forwarder keeps the original envelope sender, the check runs against the forwarder's IP, which is not in the original domain's record, and SPF fails. Nothing is wrong. The message is genuine. The record was simply never written to authorise somebody else's server.

The usual answer is the Sender Rewriting Scheme. Microsoft's documentation on SRS describes it as rewriting the MAIL FROM address on messages forwarded to external recipients, added specifically because autoforwarding is incompatible with SPF. The rewritten address sits on the forwarder's own domain and encodes the original sender's domain and local part with a hash and a timestamp, so bounces still find their way back. The From header is untouched, and the recipient still sees the original author.

SRS repairs SPF and stops there. Microsoft states directly that it does not resolve forwarded messages failing DMARC, because after the rewrite the domain SPF passed for is the forwarder's, which does not align with the From address. The only reliable route through a forward is a DKIM signature made with the From domain and left intact to the far end. That is the practical reason DKIM matters more than its reputation suggests, and why ARC exists for services that must modify messages on the way through. If your domain forwards to a mailbox elsewhere, this is the machinery you are relying on.

The reason this stopped being optional

Publishing all three used to be good practice. It is now an entry requirement at Gmail and Yahoo. Google's sender guidelines state that from 1 February 2024, senders of more than 5,000 messages a day to Gmail accounts must set up both SPF and DKIM, must have DMARC configured with the From domain aligned to either the SPF or the DKIM domain, and must keep their spam rate below 0.3% as reported by Postmaster Tools. The DMARC policy itself may be `p=none`. Marketing and subscribed messages must also support one-click unsubscribe.

Yahoo's Sender Hub sets out the same shape from February 2024: every sender should have SPF or DKIM at minimum, bulk senders need both plus a valid DMARC policy of at least `p=none` that passes, relaxed alignment is acceptable, spam rates stay below 0.3%, and unsubscribes are honoured within two days. Yahoo's page does not name a volume threshold. Microsoft's guidance for its own platform treats the three as interdependent building blocks and says anything less than all of them gives substandard protection.

What to publish, and in what order

The order matters more than the contents, because a strict policy published before you know what sends as your domain is a self-inflicted outage.

  • Publish an SPF record listing every source you already know about, ending in `~all` rather than `-all`. Microsoft's guidance recommends exactly this, starting at soft fail, discovering the remaining sources, then tightening once the list is complete.
  • Turn on DKIM signing and publish the public key under a selector. Google's guidelines set a minimum of 1024 bits and recommend 2048. Check that the `d=` value is your own domain, or the signature will pass and still not align.
  • Publish a DMARC record at `_dmarc` with `p=none` and a working `rua=` address. Send the reports to a shared mailbox, not to a person's inbox.
  • Read the aggregate reports for several weeks. They arrive as gzipped XML, roughly daily from each reporting receiver, and the thing to look for is the gap between a source that passed SPF and a source that aligned.
  • Move to `p=quarantine`, then to `p=reject`, one domain or subdomain at a time, starting with whichever carries the least mail and saving the parent domain for last. Do not try to stage the rollout with the old `pct=` tag: RFC 9989 removed it in May 2026 and tells receivers to disregard it, so a record reading `p=reject; pct=10` is now enforced against everything.

`p=none` is worth being precise about, because it is often described as protection and it is not. RFC 9989 defines it as the domain owner offering no expression of preference. It changes nothing about how a receiver treats a failing message. Its entire function is to switch on reporting, so you can see who sends as you before you decide to block anything. Microsoft's documentation calls it the value used for testing and tuning.

The failure this sequence prevents is publishing `p=reject` on day one. Almost every organisation sends more mail than it remembers: the invoicing system, the CRM, the helpdesk, appointment reminders, the payroll provider, a contact form, a survey tool somebody set up three years ago. Microsoft's documentation observes that many companies never publish SPF at all because they do not know all their own sending sources. Go straight to reject and you find out the expensive way, from customers who did not receive things. Note that all of this concerns outbound mail only; a catch-all address governs what arrives and has no bearing on these records. Domains you own but never send from should carry `p=reject`.

What these records do not do

They authenticate a domain. They do not authenticate a person, an intention or a claim. RFC 9989 is explicit that DMARC can only combat exact-domain spoofing, and in particular does not address "visually similar domain names" or abuse of the human-readable display name in the From header.

So a scammer registers something that reads like your company with an extra word in it, publishes flawless SPF, DKIM and DMARC on that domain, and sends an invoice from it. Every check passes, and every check is telling the truth: the message really did come from a server the domain's owner authorised. The domain simply is not yours, and no amount of authentication on your side prevents it. The same holds for a genuine account that has been compromised, which authenticates perfectly because it is genuine.

DKIM is narrower than it sounds too. RFC 6376 says that verifying the signature asserts the hashed content has not changed since it was signed, and asserts nothing else about protecting the end-to-end integrity of the message. It is a signature, not encryption, and the body stays readable to every machine that handles the message. Authentication raises the cost of pretending to be you. It does nothing about the more ordinary problem of your address being in circulation.

If you take one thing from this, take the shape of the failures. SPF fails when a new server starts sending, or when mail is forwarded. DKIM fails when something rewrites the message. DMARC fails when neither of the other two lines up with the name in the From field, which can happen while both are technically passing. Reading the reports for a month before tightening the policy costs nothing and avoids the only genuinely expensive mistake available here.

The YeyMail takeaway
Where an alias service fits into this

If you run aliases on a domain you own, you are the second hop described above, which is why the records matter. YeyMail's dashboard gives you three things to publish: MX pointing at mx1.yeymail.com, which is the single inbound server we run, an SPF include for yeymail.com, and a DMARC record. DKIM signing uses a shared key, with the selector published as a TXT record on your domain. Aliases are truly unlimited only on domains you own; on the shared yeymail.com domain the ceiling is 500 on Starter and 5,000 on Plus, counting every address ever created there including deleted ones. Starter is $0.99 a month or $9.48 a year, Plus is $4.99 a month or $47.88 a year, and there is no free tier. The free seven-day trial needs no card and gives the Starter feature set with lighter limits: 25 shared-domain aliases, one custom domain, and at most 20 forwarded messages a day. We hold no SOC 2 report, no ISO certification and no third-party audit, and we say so rather than let a badge imply otherwise.

Start free — one alias per signup7-day trial · No credit card

Sources

Common questions

Do I need all three records, or is SPF enough?

For mail to reach a large provider reliably, all three. Google's sender guidelines require both SPF and DKIM plus a DMARC record for senders above its bulk threshold, and Yahoo asks bulk senders for both plus a valid DMARC policy. Below those thresholds SPF or DKIM alone will often get through, but only DMARC ties either of them to the address your recipient actually sees.

Why does my mail pass SPF but fail DMARC?

Because SPF is checked against the envelope sender and DMARC is checked against the visible From address. If a service sends on your behalf using its own bounce domain, SPF passes for that domain and then fails to align with yours. The fix is either to move the envelope domain under your own domain, or to have the service DKIM-sign with your domain in the d= tag.

Does p=none protect anything?

No. RFC 9989 defines p=none as the domain owner offering no expression of preference about failing mail, so receivers treat it much as they would treat no policy at all. Its value is that it switches on aggregate reporting, which is how you find out what sends as your domain before you start blocking. Microsoft's documentation describes it as the value for testing and tuning.

Will publishing p=reject break forwarded mail?

It can. A forwarded message fails SPF at the second hop because the forwarding server is not in your record, so if the DKIM signature has also been broken in transit, DMARC fails and your policy tells the receiver to reject. Making sure outbound mail is DKIM-signed with your own domain, and that nothing in the path rewrites the signed parts, is what keeps forwarding working under a strict policy.

How many includes can I have in an SPF record?

RFC 7208 requires implementations to stop after ten terms that trigger DNS queries, counting include, a, mx, ptr, exists and redirect, and to return a permanent error beyond that. Some includes expand into further lookups inside themselves, so the real ceiling is lower than ten entries in your own record. If SPF stops working shortly after you add a supplier, check this first.

Does DKIM encrypt my email?

No. DKIM is a signature over the body and a selected set of headers, and RFC 6376 says that verifying the signature asserts the hashed content has not changed since it was signed, and asserts nothing else about protecting the end-to-end integrity of the message. The message stays as readable to every server that handles it as it was before. DKIM also says nothing about whether the contents are honest, only about who signed them.

Keep reading

Guide
Catch-All Email: Setup, Spam Risks and Fixes
Guide
How to Set Up Email Aliases in an Hour: A Practical Plan
Privacy guide
Can Your Email Provider Read Your Email?