Skip to content

Technical guide

Email authentication with SPF, DKIM and DMARC

SPF, DKIM and DMARC let a receiving mail server check that a message using your domain was sent with your permission. This guide covers each record, how they combine, and how to move DMARC to enforcement without losing real mail.

Reviewed October 2026.

How they work together

Email was designed without any check on who a message claims to be from. The From address a reader sees is text in the message, and anyone can write any domain there. Three records published in DNS let a receiving server test that claim for your domain.

MechanismWhat it checksPublished at
SPFWhether the sending server's IP address may send for the envelope sender's domain (the MAIL FROM, often shown as Return-Path)A TXT record at the domain, starting v=spf1
DKIMA cryptographic signature over the message, made with a key that belongs to the signing domain (d=)A TXT record at <selector>._domainkey.<domain>
DMARCThat SPF or DKIM passed for a domain matching the visible From address, and what to do when neither didA TXT record at _dmarc.<domain>

SPF and DKIM each authenticate a domain, but not necessarily the one the reader sees. A message from invoices@example.com can pass SPF for a mailing provider's bounce domain and DKIM for the provider's own domain while proving nothing about example.com. DMARC closes that gap with alignment: it passes only when SPF or DKIM passes for a domain that matches the From domain.

Alignment

Under relaxed alignment, the default, the authenticated domain and the From domain need only share an organisational domain, so mail.example.com aligns with example.com. Under strict alignment (adkim=s, aspf=s) they must be identical. One aligned pass, from either SPF or DKIM, is enough for DMARC to pass.

Forwarding is why DKIM matters most. A forwarder resends the message from its own servers, so SPF usually fails at the final destination, while a DKIM signature normally survives if the message is not changed on the way. RFC 9989 says a domain that publishes p=reject must not rely on SPF alone and must sign its mail with DKIM.

SPF

An SPF record (RFC 7208) lists the servers allowed to send mail with your domain as the envelope sender. The receiving server compares the connecting IP address against it. A typical record, published as a TXT record at the domain: v=spf1 include:_spf.google.com ip4:203.0.113.10 -all

  • include: brings in a provider's own list, ip4: and ip6: name addresses directly, and a and mx allow the domain's own web or mail servers.
  • The final term covers everyone else. -all (fail) asks receivers to treat any other sender as unauthorised; ~all (softfail) is weaker and useful while you are still finding every sender. Never use +all, which authorises the whole internet, or ?all, which says nothing.
  • Publish exactly one SPF record per name. Two records make SPF evaluation return an error (permerror), and receivers then have no usable SPF for the domain.
  • Evaluation may use at most 10 DNS lookups. include, a, mx, ptr, exists and redirect each count, including those inside included records, and going over the limit is also a permerror. Remove includes for services you no longer use before adding new ones.
  • Do not use ptr. RFC 7208 says it should not be published.

SPF checks the envelope sender, not the From address. When a third-party service sends as you, its envelope domain is often its own, so SPF passes for the provider and does not align with your domain. Many services let you set a custom return-path or bounce domain under your own domain, which is what makes SPF align. Where a service cannot, aligned DKIM has to carry DMARC for that mail.

  • SPF checker Check a domain's SPF record, its all mechanism and how many of the 10 DNS lookups it uses.

Findings and fixes are in the SPF check reference.

DKIM

With DKIM (RFC 6376), the sending service signs each message with a private key. The signature names the signing domain (d=) and a selector (s=), and the receiver fetches the public key from a TXT record at <selector>._domainkey.<domain>. A valid signature shows that the signing domain took responsibility for the message and that the signed parts were not changed.

  • Turn on DKIM in every service that sends as your domain: the mailbox provider, newsletter and marketing tools, the helpdesk, billing and the website's contact form. Each has its own selector, usually given to you as a TXT or CNAME record to publish.
  • Sign with your own domain. A service that signs with its own domain produces a valid signature that does not align with your From address.
  • Use RSA keys of at least 2048 bits. RFC 8301 sets 1024 bits as the minimum, recommends 2048, and forbids rsa-sha1 signatures.
  • Rotate keys by publishing a new selector, moving signing to it, then retiring the old one. Publishing the old selector with an empty key (p=) marks it as revoked.

Findings and fixes are in the DKIM check reference.

DMARC

DMARC is published as a TXT record at _dmarc.<domain>. It tells receivers what you want done with mail that fails, and where to send reports about it. In May 2026 RFC 9989 replaced RFC 7489 as the DMARC specification and made it a standards-track protocol, with aggregate reports defined in RFC 9990 and failure reports in RFC 9991.

A typical record while monitoring: v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com

TagMeaningNotes
v=DMARC1VersionMust come first
p=Policy for the domain: none, quarantine or rejectQuarantine usually means the spam folder
sp=Policy for existing subdomainsDefaults to p
np=Policy for subdomains that do not existDefaults to sp, then p
rua=Where to send aggregate reportsA mailbox, or a reporting service
ruf=Where to send failure reports about single messagesOptional, and may contain personal data
adkim=, aspf=Alignment mode for DKIM and SPF: r relaxed or s strictDefault r
t=Test mode: y or nNew in RFC 9989, default n

Aggregate reports are XML files from receivers listing the IP addresses that sent mail using your domain, and whether each passed SPF, DKIM and DMARC. They are how you find senders nobody told you about, and how you see your domain being spoofed. The raw XML is tedious to read; a reporting service or parser helps.

Records written for RFC 7489 may carry pct=, which asked receivers to apply the policy to a percentage of failing mail. RFC 9989 removes it because receivers applied it inconsistently, and a receiver following the new standard ignores it as an unknown tag. Its replacement is t=y, under which failing mail is handled one level below the published policy: p=reject; t=y as quarantine, and p=quarantine; t=y as none.

Subdomains follow the parent record unless they publish their own. sp= sets the policy for subdomains that exist, and np= for names that do not exist at all, which are a common choice for spoofing.

Findings and fixes are in the DMARC check reference.

A staged DMARC rollout

Publishing p=reject on day one risks blocking real mail from a service nobody remembered. Go in stages, and let the reports tell you when to move.

StageRecordMove on when
Monitorv=DMARC1; p=none; rua=mailto:...Every legitimate source in the reports passes with aligned SPF or DKIM
Quarantinev=DMARC1; p=quarantine; rua=mailto:...Reports show no legitimate mail failing, and nobody reports missing mail
Rejectv=DMARC1; p=reject; rua=mailto:...This is the end state; keep reading the reports
  1. List every service that sends mail as your domain, including those that finance, marketing and the website use. Ask, then check the reports for what nobody mentioned.
  2. Publish p=none with a rua address that someone reads.
  3. For each legitimate source, set up DKIM signing with your domain and, where the service allows it, an aligned return-path for SPF.
  4. Move to p=quarantine. Watch the reports and the support inbox.
  5. Move to p=reject. Keep rua in place, so that new senders and abuse of your domain stay visible.

How long each stage takes depends on how many services send for you. NCSC guidance says many organisations move on from p=none after about six to eight weeks, advises at least four weeks of monitoring once quarantine applies to all mail, and says many move from quarantine to reject after about three months. If real mail starts failing, step back a stage, fix the source and try again.

NCSC examples step up gradually with pct. Under RFC 9989, use t=y for a trial step instead, or move to the full policy once the reports are clean.

Domains that send no mail

Parked, defensive and web-only domains are still used for spoofing, because nothing says they should not send. Publish records that say the domain sends nothing.

RecordNameValue
SPFThe domainv=spf1 -all
DMARC_dmarc under the domainv=DMARC1; p=reject; with an optional rua=
Null MX (RFC 7505)The domain0 ., if it receives no mail either
DKIM (optional)*._domainkey under the domainv=DKIM1; p=

This is the set NCSC recommends for parked domains. The null MX stops other servers trying to deliver mail to the domain's web server instead, and the empty DKIM key states that nothing is signed. Findings and fixes are in the non-sending domain check reference.

Checking your domain

  • Email security checker Check MX, SPF, DMARC and DKIM together, and the protection of a domain that sends no mail.
  • SPF checker Check a domain's SPF record, its all mechanism and how many of the 10 DNS lookups it uses.
  • DKIM checker Look up a DKIM key at your selector or at common ones, with its key type and size.
  • DMARC checker Look up a domain's DMARC record, read its policy and reporting, and see what to change.

What a check can show, and what it cannot

Ironfang can check

  • Whether SPF and DMARC records are published and parse, and whether a DKIM key exists at a given selector
  • SPF's final all term and how many DNS lookups it needs
  • The DMARC policy and whether aggregate reports are requested
  • Whether a domain with no MX records declares that it sends no mail

The organisation must establish

  • The list of services allowed to send as the domain, and who owns each
  • That DKIM signing with your domain is turned on in each of those services
  • Who reads the DMARC reports, and what they do about an unknown sender
  • The decision to move to quarantine and reject, and the evidence behind it

The External Security Check runs the same email checks on a verified domain alongside DNS, TLS and HTTP headers, keeps the results with the domain's history, and can recheck on a schedule.

Sources

Checked on the review date above. Standards and schemes change; the source is the authority.