esc
Email DNS & Email

SPF, DKIM and DMARC Explained: How Email Authentication Works

By helpers.work Updated 14 min read
SPF, DKIM and DMARC DNS records for example.com, showing the SPF TXT record, the DKIM selector record and the DMARC policy record with an aligned pass result

SPF, DKIM and DMARC are three DNS records that let a receiving mail server check whether a message really comes from your domain. SPF lists the servers allowed to send your mail. DKIM signs each message with a key published in DNS. DMARC checks that at least one of them passed for the domain in the visible From: address, and tells the receiver what to do when neither did.

Without them, anyone can send email that claims to be from your domain, and receivers have no strong reason to trust your real mail. Since 2024, Gmail and Yahoo require them from bulk senders, and missing records are one of the most common causes of mail going to spam.

SPF, DKIM and DMARC at a glance

SPF DKIM DMARC
Question it answers Is this server allowed to send? Is the message signed and unchanged? Does a passing check match the From domain?
DNS name example.com selector._domainkey.example.com _dmarc.example.com
Record type TXT TXT (sometimes a CNAME to the provider) TXT
Checks which domain Envelope sender (Return-Path) The d= domain in the signature The visible From: domain
Survives forwarding Usually no Usually yes Yes, if DKIM survives
Tells receivers what to do No No Yes: none, quarantine or reject

You can check all three for any domain with the SPF Checker, DKIM Checker and DMARC Checker.

SPF: which servers may send for your domain

SPF (Sender Policy Framework, RFC 7208) is a single TXT record at your domain that lists the servers permitted to send mail for it. The receiver takes the IP address of the connecting server and checks whether your record allows it.

example.com.  3600  IN  TXT  "v=spf1 ip4:203.0.113.10 include:_spf.google.com include:mailgun.org -all"

Read from left to right, this record says: the server at 203.0.113.10 may send, Google Workspace and Mailgun may send, and everything else should fail.

SPF mechanisms and qualifiers

Part Meaning Costs a DNS lookup
v=spf1 Marks the record as SPF. Must come first. —
ip4: / ip6: An address or CIDR range, such as ip4:203.0.113.0/24. No
include: Also allow everything the other domain's SPF record allows. Yes
a / mx Allow the IPs of the domain's A/AAAA or MX hosts. Yes
exists: Advanced macro-based check, mostly used by large providers. Yes
ptr Reverse-DNS match. Deprecated; do not use. Yes
redirect= Use another domain's SPF record instead of this one. Yes
-all Fail anything not matched. No
~all Softfail: accept but treat as suspicious. No
?all Neutral: no opinion. No
+all Allow the whole internet. Never use this. No

The prefix before a mechanism is its qualifier. + (pass) is the default, so include:mailgun.org means +include:mailgun.org. Once DMARC is in place, ~all and -all behave almost the same in practice, because DMARC makes the final decision. -all is still the clearer choice for a domain whose senders are fully known.

The 10 DNS lookup limit

To stop SPF from being abused for DNS amplification, a receiver may perform at most 10 DNS lookups while evaluating your record, including lookups inside nested include: records. ip4, ip6 and all are free. If the limit is exceeded, the result is permerror, and receivers treat SPF as failed.

This limit is easy to hit. Google Workspace, Microsoft 365, a CRM, a helpdesk and a newsletter platform can use most of it on their own. The SPF Checker expands every include and counts the lookups for you.

Two other rules cause the same permerror:

  • Only one SPF record per domain. Two TXT records that both start with v=spf1 are invalid. Merge them into one.
  • Syntax errors, such as a typo in a mechanism name or a missing space.

What SPF does not protect

SPF checks the envelope sender (also called the Return-Path or MAIL FROM), a technical address used for bounces. The recipient never sees it. The address they do see is in the From: header, and SPF does not look at it. A spammer can pass SPF for their own domain and still put your domain in the From: line.

SPF also breaks on forwarding. When a message is forwarded, the forwarding server sends it from its own IP address, which is not in your record. Both gaps are why SPF alone is not enough.

DKIM: a signature that proves the message is yours

DKIM (DomainKeys Identified Mail, RFC 6376) signs outgoing messages with a private key. The receiver finds the matching public key in DNS and verifies the signature. A valid signature proves that the message was signed by the domain in the d= tag and that the signed headers and body were not changed in transit.

The signature is added as a header:

DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector1;
    h=from:to:subject:date:message-id; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
    b=Lx8r3Vq...

The public key is published under the selector from s=:

selector1._domainkey.example.com.  3600  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
  • v=DKIM1 marks the record as a DKIM key.
  • k=rsa is the key type. ed25519 also exists, but not all receivers support it, so RSA is still required.
  • p= is the Base64-encoded public key. An empty p= means the key has been revoked.

Because the signature travels inside the message, DKIM survives normal forwarding. That makes it the more reliable half of DMARC.

DKIM selectors

A selector lets one domain publish several keys at once, one per sending service or per key generation. There is no DNS query that lists all selectors for a domain. To find one, open a message you received, look at the DKIM-Signature header and read the s= value.

Provider Typical selectors
Google Workspace google
Microsoft 365 selector1, selector2
Amazon SES Three random tokens (CNAMEs)
SendGrid s1, s2
Mailchimp / Mandrill k1, k2, k3

Selectors can differ per account, so treat this table as a starting point. Once you know the selector, the DKIM Checker fetches the record and reports the key type and length.

Key length and rotation

  • Use 2048-bit RSA keys. 1024-bit keys still work but are considered weak, and major receivers treat signatures made with shorter keys as if the message were unsigned.
  • A 2048-bit key is longer than the 255-character limit for a single TXT string. DNS providers split it into several quoted strings in one record, which is valid.
  • Rotate keys by publishing a new selector, switching signing to it, then leaving the old key in DNS for a few days so messages still in transit can be verified. After that, revoke the old key with an empty p=.

DMARC: the policy that ties SPF and DKIM together

DMARC (Domain-based Message Authentication, Reporting and Conformance, RFC 7489) does three things: it checks alignment with the From: domain, it tells receivers what to do when a message fails, and it asks them to send you reports.

The record is always published at the _dmarc subdomain:

_dmarc.example.com.  3600  IN  TXT  "v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=r; aspf=r"

A DMARC record placed at example.com itself is ignored. This is a common setup mistake.

DMARC alignment

A message passes DMARC when at least one of these is true:

  • SPF passes and the envelope sender domain aligns with the From: domain, or
  • DKIM passes and the signature's d= domain aligns with the From: domain.

Alignment is relaxed by default: the two domains only need to share the same organizational domain. Strict alignment (adkim=s, aspf=s) requires an exact match.

From: domain Authenticated domain Relaxed Strict
example.com example.com Pass Pass
example.com mail.example.com Pass Fail
example.com bounces.esp-provider.net Fail Fail

The last row is the classic "SPF passes but DMARC fails" case. The email service's own bounce domain passes SPF, but it has nothing to do with your From: domain.

DMARC tags

Tag Example Meaning
v v=DMARC1 Required, and must come first.
p p=quarantine Required. Policy for the domain: none, quarantine, reject.
sp sp=reject Policy for subdomains. Defaults to the value of p.
rua rua=mailto:[email protected] Where to send daily aggregate reports.
ruf ruf=mailto:[email protected] Where to send failure reports. Few receivers still send them.
pct pct=25 Apply the policy to only this percentage of failing mail. Default 100.
adkim adkim=s DKIM alignment: r relaxed (default) or s strict.
aspf aspf=s SPF alignment: r relaxed (default) or s strict.
fo fo=1 When to generate failure reports.

If reports go to a mailbox on a different domain, that domain must authorize it with a TXT record such as example.com._report._dmarc.reports.example.net containing v=DMARC1. Hosted DMARC reporting services usually set this up for you.

p=none, p=quarantine and p=reject

  • p=none: monitoring only. Nothing is blocked, but you receive reports. It does not protect your domain from spoofing.
  • p=quarantine: failing messages go to the spam or junk folder.
  • p=reject: failing messages are refused during delivery. This is the goal for a domain you control fully.

The DMARC Checker shows the policy, subdomain policy, alignment modes and reporting addresses of any domain.

DMARC reports

Aggregate (rua) reports are XML files that large receivers send about once a day. Each one lists the IP addresses that sent mail using your domain, how many messages they sent, and whether SPF, DKIM and alignment passed. They are the only reliable way to discover every service that sends as you, including the forgotten ones, before you enforce a policy. Most teams use a DMARC report analyzer rather than reading raw XML.

How receivers evaluate a message

When a message arrives, the receiving server roughly does this:

  1. Checks SPF against the connecting IP and the envelope sender domain.
  2. Verifies every DKIM signature in the message.
  3. Looks up the DMARC record for the From: domain.
  4. Checks whether a passing SPF or DKIM result aligns with the From: domain.
  5. Applies the DMARC policy if nothing aligned, and records the result for your reports.
  6. Combines the result with reputation and content filtering to decide on inbox or spam.

Passing DMARC does not guarantee the inbox. It proves who sent the message, and reputation does the rest. Failing DMARC under p=reject, though, stops delivery completely.

Reading the Authentication-Results header

Receivers write their verdict into an Authentication-Results header. In Gmail, open a message and choose Show original; in Outlook, view the message source or headers.

Authentication-Results: mx.google.com;
    dkim=pass [email protected] header.s=selector1;
    spf=pass (google.com: domain of [email protected] designates 203.0.113.10 as permitted sender) [email protected];
    dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
  • dkim=pass [email protected] shows which domain signed the message.
  • smtp.mailfrom= is the envelope sender that SPF checked.
  • header.from= is the visible From: domain that DMARC compared against.
  • dis= is the action taken: NONE, QUARANTINE or REJECT.

Gmail, Yahoo and Outlook sender requirements

Since February 2024, Gmail and Yahoo require the following from bulk senders, which Google defines as those sending more than about 5,000 messages a day to Gmail addresses:

  • SPF and DKIM for the sending domain.
  • A DMARC record with at least p=none.
  • Alignment of the From: domain with SPF or DKIM.
  • One-click unsubscribe (RFC 8058) for marketing mail, and a low spam complaint rate (Google asks for under 0.3%).

All senders, even small ones, need at least SPF or DKIM, valid forward and reverse DNS for their sending IPs, and TLS for delivery. Microsoft introduced similar requirements for high-volume senders to Outlook.com, Hotmail and Live addresses in 2025. Meeting these rules is now a baseline for deliverability, not an optional extra.

A safe rollout plan

  1. List every service that sends as your domain: mailboxes, CRM, billing, helpdesk, newsletters, monitoring and web forms.
  2. Publish one SPF record that includes all of them, and check that it stays within 10 lookups.
  3. Enable DKIM in every service, using your own domain as d=. Most providers give you one or more CNAME or TXT records to publish.
  4. Publish DMARC with p=none and a rua address.
  5. Read reports for two to four weeks. Fix every legitimate source that fails alignment.
  6. Move to p=quarantine, optionally starting with a low pct, then raise it to 100.
  7. Move to p=reject once reports stay clean.

Jumping straight to p=reject without reading reports is the fastest way to silently block your own invoices, password resets and newsletters. Monitor first.

DNS changes are cached, so allow for the record's TTL before you judge a change. The guide to DNS propagation explains how long that takes.

Troubleshooting common failures

SPF permerror

Usually caused by more than 10 lookups or by two SPF records. Remove includes for services you no longer use, replace a and mx with explicit ip4: ranges where they are stable, and consider moving marketing mail to a subdomain such as news.example.com with its own SPF record. Automated "SPF flattening" also works, but it breaks silently when a provider changes its IP addresses.

SPF passes but DMARC fails

The envelope sender belongs to your email provider, not to you. In the provider's settings, configure a custom return-path or custom MAIL FROM domain (for example bounce.example.com), and enable DKIM signing with your own domain. Either one is enough to align. DKIM is the better choice because it also survives forwarding.

DKIM fails after forwarding or on mailing lists

Mailing lists often add a footer or a [list] tag to the subject, which changes signed content and breaks the signature. Many lists now rewrite the From: address to their own domain to avoid DMARC failures. Large receivers also use ARC (Authenticated Received Chain, RFC 8617) to trust the authentication results recorded by a forwarder.

DKIM record not found

Check the selector in a real message header, then make sure the record name is selector._domainkey.example.com. A common mistake is entering the full name in a DNS panel that already appends the domain, which creates selector._domainkey.example.com.example.com. The DNS Lookup tool shows what is actually published.

Legitimate mail rejected after enforcing DMARC

Find the sending IP in your aggregate reports, identify the service, and either add DKIM for it or move it to a subdomain. If the problem is urgent, temporarily drop back to p=quarantine or p=none while you fix it.

Protecting domains that never send email

Parked and redirect-only domains are popular for spoofing because nobody watches them. Lock them down with three records:

example.net.         IN  TXT  "v=spf1 -all"
_dmarc.example.net.  IN  TXT  "v=DMARC1; p=reject"
example.net.         IN  MX   0 .

The last line is a null MX (RFC 7505), which tells other servers that the domain does not accept mail.

Summary

SPF says which servers may send for your domain, DKIM proves a message was signed by your domain and not changed, and DMARC requires one of them to match the From: address and tells receivers what to do when neither does. Publish all three, start DMARC at p=none, read the reports, and move to p=reject once every legitimate sender aligns.

Check your current records with the SPF Checker, DKIM Checker and DMARC Checker, and use the DNS Lookup to confirm what your DNS provider is serving.

FAQ

Frequently asked questions

What is the difference between SPF, DKIM and DMARC?

SPF lists the servers allowed to send mail for a domain. DKIM adds a cryptographic signature that proves the message came from the domain and was not changed. DMARC checks that SPF or DKIM passed for the same domain as the visible From address and tells receivers what to do when it did not.

Do I need all three of SPF, DKIM and DMARC?

Yes. Gmail, Yahoo and Outlook.com expect bulk senders to publish all three, and DMARC can only pass when SPF or DKIM passes and aligns. DKIM is the most important of the two because it survives forwarding.

Why does my email pass SPF but still fail DMARC?

SPF checks the envelope sender (Return-Path), not the visible From address. If your email service uses its own bounce domain, SPF passes for that domain but does not align with yours. Set up a custom return-path domain or DKIM signing with your own domain to fix it.

Where is the DMARC record published?

At the _dmarc subdomain as a TXT record, for example _dmarc.example.com. A DMARC record published at the domain apex is ignored.

Should I use p=none, p=quarantine or p=reject?

Start with p=none to collect reports without affecting delivery. Move to p=quarantine when reports show all legitimate mail passes, then to p=reject. Only p=quarantine and p=reject actually protect your domain from spoofing.

Does SPF work when email is forwarded?

Usually not. The forwarding server sends from its own IP address, which is not in your SPF record. DKIM normally survives forwarding because the signature travels with the message, unless the forwarder changes the signed content.

Try it yourself

Related tools

All tools

More guides in the helpers.work blog

Practical, no-nonsense guides on DNS, email, networking and security — plus 68 free tools to go with them.

Read the blog Browse all tools