All articlesDeliverability

SPF, DKIM and DMARC: The Complete Email Authentication Setup Guide

Step-by-step instructions for publishing SPF, DKIM and DMARC records correctly, understanding alignment, reading reports, and moving safely to p=reject.

The SMTPTester Team November 3, 2025 18 min read

Why email authentication decides whether you reach the inbox

Email was designed in an era when nobody expected the sender address to be a lie. Nothing in the base SMTP protocol stops a machine from claiming to be billing@yourbank.com. Every anti-spoofing control in use today is a layer added on top, and all three of the important ones live in DNS: SPF, DKIM and DMARC.

Since February 2024, Gmail and Yahoo require bulk senders to authenticate with SPF and DKIM, publish a DMARC policy, and keep spam complaints under 0.3 percent. Microsoft followed with similar requirements for Outlook.com in 2025. Authentication is no longer a best practice you get to schedule for next quarter — it is the price of entry.

This guide walks through each record, how they interact, and the exact order to deploy them without breaking legitimate mail.

The three records at a glance

RecordQuestion it answersWhere it lives
SPFIs this IP allowed to send for this domain?TXT at the domain root
DKIMWas this message altered, and does the signature match a key the domain published?TXT at selector._domainkey.domain
DMARCWhat should a receiver do when SPF and DKIM fail, and where do I send reports?TXT at _dmarc.domain

SPF validates the *envelope* sender. DKIM validates the *message*. DMARC ties either of them back to the visible From header — which is the only address a human ever sees. That last point is why DMARC matters: without it, an attacker can pass SPF for their own domain while displaying your brand in the From field.

Step 1: Publish SPF

An SPF record is a single TXT record at your domain root listing the servers permitted to send on your behalf.

v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.20 -all

Breaking that down:

  • v=spf1 — version marker, always first.
  • include: — delegates to another domain's SPF record; use the value your provider documents.
  • ip4: / ip6: — literal addresses for servers you run yourself.
  • -all — hard fail: anything not listed is unauthorised.

### The rules people break

One SPF record per domain. Two v=spf1 TXT records is a permanent error and causes every check to fail. Merge them into one.

Ten DNS lookup limit. Each include, a, mx, ptr and redirect costs a lookup, and those nest. Exceed ten and receivers return permerror, which DMARC treats as a failure. Count them before you publish; if you are near the limit, flatten rarely-changing includes into literal IP ranges or use an SPF-flattening service.

Prefer `-all` over `~all`. Soft fail (~all) was useful while you were testing. Once DMARC is enforcing, hard fail is the honest signal.

Never use `ptr`. It is deprecated, slow, and many receivers ignore it entirely.

### Validating SPF

Query the record and count lookups:

dig +short TXT yourdomain.com
dig +short TXT _spf.google.com

If the returned string is split across multiple quoted chunks, that is normal — DNS strings cap at 255 characters and resolvers concatenate them.

Step 2: Enable DKIM

DKIM adds a cryptographic signature header to every outgoing message. The receiver fetches your public key from DNS and verifies that the signed headers and body were not modified in transit.

Your provider generates the key pair. You publish the public half:

Name:  s1._domainkey.yourdomain.com
Type:  TXT
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhki...

The s1 part is the selector. It lets you publish several keys at once, which is what makes rotation painless: publish a new selector, switch signing to it, then remove the old record a week later.

### DKIM rules that matter

  • Use 2048-bit keys. 1024-bit is still accepted but is being phased out; some receivers already downgrade trust.
  • Sign with your own domain, not the provider's. If the d= tag in the signature says sendgrid.net, DKIM passes but DMARC alignment fails.
  • Sign the headers that matter: From, To, Subject, Date, Message-ID, MIME-Version, Content-Type.
  • Watch for mailing lists. They modify subjects and append footers, which breaks the body hash. This is expected and is exactly what DMARC's "either SPF or DKIM may pass" rule exists to absorb.
  • Rotate keys at least annually.

Verify a published key:

dig +short TXT s1._domainkey.yourdomain.com

Then send a test message to a mailbox you control and inspect the raw headers for dkim=pass.

Step 3: Understand alignment before you publish DMARC

This is the concept that trips up almost everyone.

DMARC does not simply ask "did SPF pass?" It asks "did SPF pass for a domain that aligns with the From header?"

  • SPF alignment compares the From domain with the Return-Path (envelope sender) domain.
  • DKIM alignment compares the From domain with the d= value in the DKIM signature.

DMARC passes if *either* mechanism passes and is aligned. This is why a message can show spf=pass in its headers and still fail DMARC: the SPF check passed for the provider's bounce domain, not for yours.

Relaxed alignment (the default) accepts subdomains — mail.yourdomain.com aligns with yourdomain.com. Strict alignment requires an exact match. Start relaxed.

The fix for SPF misalignment is usually a custom return path or custom bounce domain in your provider's dashboard, which adds a CNAME under your domain so the envelope sender becomes bounces.yourdomain.com.

Step 4: Publish DMARC in monitoring mode

Never start at enforcement. Start here:

Name:  _dmarc.yourdomain.com
Type:  TXT
Value: v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; fo=1

Tags you should know:

  • p= — policy: none, quarantine, or reject.
  • sp= — a different policy for subdomains.
  • rua= — where aggregate XML reports are sent (daily, one per receiver).
  • ruf= — forensic reports; most receivers no longer send these for privacy reasons.
  • pct= — apply the policy to a percentage of mail, for gradual rollout.
  • adkim= / aspf=r for relaxed (default) or s for strict.
  • fo=1 — request a report whenever any mechanism fails.

Leave this in place for two to four weeks. You are looking for one thing: a complete inventory of every system that sends mail as your domain. Almost every organisation discovers a forgotten one — a helpdesk tool, a billing system, an old marketing platform, a monitoring script on a server nobody owns.

Step 5: Read the reports

Aggregate reports arrive as gzipped XML. Each record looks roughly like this:

<record>
  <row>
    <source_ip>203.0.113.20</source_ip>
    <count>412</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
</record>

Reading raw XML for more than a handful of sources is impractical; use a DMARC reporting service to aggregate them. What you are working towards is a report where every IP with meaningful volume shows dkim=pass and spf=pass, and the remaining failures are either spoofing attempts or forwarded mail.

Forwarding is the most common benign failure. When a recipient auto-forwards your message, SPF breaks because the forwarding server is not in your record, but DKIM survives if the body was not modified. This is precisely the scenario DMARC's either/or rule was designed for.

Step 6: Move to enforcement gradually

Once your legitimate sources all pass, tighten in stages:

  1. p=quarantine; pct=10 — one week.
  2. p=quarantine; pct=50 — one week.
  3. p=quarantine; pct=100 — two weeks.
  4. p=reject; pct=100.

At each step, watch the reports and your support inbox. If a legitimate source starts failing, roll back one step rather than pushing forward.

Also protect domains you never send from. A parked domain should carry:

v=spf1 -all
v=DMARC1; p=reject;

Attackers actively look for unprotected sibling domains.

Beyond the big three

BIMI displays your logo next to authenticated messages in supporting clients. It requires p=quarantine or p=reject, a square SVG Tiny PS logo, and for Gmail a Verified Mark Certificate. It is a marketing win, not a deliverability one, but it is a strong incentive to finish DMARC enforcement.

MTA-STS tells receiving servers that mail to your domain must use TLS with a valid certificate, closing the downgrade-attack gap in opportunistic STARTTLS. It needs a DNS record plus a policy file served over HTTPS at mta-sts.yourdomain.com.

TLS-RPT delivers daily reports about TLS negotiation failures for your domain — a cheap early-warning system for certificate problems.

Common failure patterns and fixes

SymptomLikely causeFix
spf=pass, dmarc=failReturn-Path is the provider's domainConfigure a custom bounce domain
dkim=pass, dmarc=failSignature uses provider's d=Enable domain-level DKIM signing
spf=permerrorMore than 10 DNS lookupsFlatten or remove includes
Intermittent DKIM failuresMessage modified by a list or gatewayExpected; rely on SPF alignment
Reports show unknown IPsShadow IT or spoofingInventory, then enforce

A realistic 30-day rollout plan

  • Days 1–2: Inventory every sending system. Publish or correct SPF. Enable DKIM everywhere.
  • Day 3: Publish p=none with aggregate reporting.
  • Days 4–17: Collect reports. Fix alignment on each source. Configure custom return paths.
  • Days 18–24: p=quarantine with pct ramping from 10 to 100.
  • Days 25–30: p=reject. Lock down parked domains. Consider MTA-STS and BIMI.

Verify at every step

DNS changes propagate unevenly and typos are silent. After each edit, query the record directly, send a test message to a mailbox you control, and read the raw headers. Confirming that your SMTP relay itself still authenticates correctly with SMTPTester at the same time closes the loop: transport working, identity proven, reports flowing.

Subdomain strategy in detail

DMARC applies to a domain and, by inheritance, its subdomains. That inheritance is a powerful tool once you understand it.

Publishing p=reject at yourdomain.com protects every subdomain automatically unless you override with sp=. This matters because attackers frequently spoof plausible subdomains such as billing.yourdomain.com that you never created. With a root policy of reject and no override, those attempts fail.

A common staged approach uses sp= to move at different speeds:

v=DMARC1; p=reject; sp=none; rua=mailto:dmarc@yourdomain.com

This enforces on the root domain, where you control the traffic, while you continue collecting data on subdomains that may still have unidentified senders. Once subdomain reports are clean, remove the sp tag so inheritance takes over.

Third-party senders

Almost every organisation sends through services it does not think of as email systems: helpdesk platforms, invoicing tools, CRM systems, survey tools, applicant tracking systems, calendar invitations. Each one needs to authenticate as your domain.

For each vendor, ask two questions:

  1. Can it sign DKIM with our domain? Most reputable vendors support this by publishing a CNAME under your domain that points to their key. Always choose this over SPF-only, because DKIM survives forwarding and does not consume a DNS lookup.
  2. Can it use a custom return path? If yes, configure it. This fixes SPF alignment.

If a vendor supports neither, its mail cannot pass DMARC as your domain. Options are to send from a subdomain with a looser policy, to move to a vendor that does support authentication, or to accept that the mail will be quarantined once you enforce.

Keep a living register of these senders. It is the single most useful artifact for the whole project and the thing DMARC reports will otherwise force you to reconstruct from scratch.

Troubleshooting DNS itself

Authentication failures are frequently DNS failures wearing a disguise.

  • Record split incorrectly. A DKIM public key exceeds the 255-character limit for a single DNS string. Providers must split it into multiple quoted strings within one TXT record. Some DNS panels do this automatically; some require you to do it manually; a few do it wrong.
  • Trailing dots and duplicated domain. Entering s1._domainkey.yourdomain.com in a panel that already appends the zone produces s1._domainkey.yourdomain.com.yourdomain.com. Always verify with dig after publishing.
  • Wildcard records shadowing. A * TXT record can interfere with lookups on some resolvers.
  • CNAME conflicts. You cannot have a CNAME and a TXT record at the same name.
  • Low TTL during rollout. Set TTLs to 300 seconds while you are iterating, then raise them once stable.

What success looks like

After a completed rollout you should be able to state, with evidence:

  • Every legitimate sending source is inventoried and documented.
  • DMARC aggregate reports show 100 percent alignment for your own traffic.
  • The policy is p=reject and has been for at least a month without incident.
  • Parked and unused domains are locked down.
  • Someone owns the reports and reviews them weekly.

That last point is what separates a project from a practice. Authentication is not a task you complete; it is a state you maintain as new tools are adopted and old ones retired.

Test your SMTP server now

Apply what you just learned. Free, no signup, results in seconds.

Open the tool →

Continue reading