SPF, DKIM, and DMARC: A Practical Setup Guide

Your domain sends email. Anyone else can send email that claims to come from your domain. SPF, DKIM, and DMARC exist to close that gap. Three DNS records, published in the right order, turn your domain from an easy spoof target into a verified sender.

Verdict: What You Need to Publish (TL;DR)

Publish three TXT records in DNS, in this order: SPF first, DKIM second, DMARC third. Start DMARC at p=none and tighten it later. That sequence covers the Gmail and Yahoo sender requirements.

SPF lists the servers allowed to send mail for your domain. DKIM adds a cryptographic signature that proves a message left your infrastructure untampered. DMARC ties the two together and tells receivers what to do with mail that fails both checks. No single record does the whole job.

Your sending volume decides how strict the requirements get. Under 5,000 messages a day to Gmail accounts, SPF or DKIM plus a spam rate below 0.3% meets the bar. Above 5,000 a day, Gmail counts you as a bulk sender and requires SPF and DKIM and DMARC together, with DMARC alignment between your From domain and the authenticated domain. Yahoo mirrors the same thresholds: spam rate below 0.3%, DMARC at p=none as a minimum, and DKIM keys of at least 1024 bits.

Google adds one sequencing rule that trips up new setups. Let SPF and DKIM authenticate your mail for at least 48 hours before you switch DMARC on. I recommend treating that 48-hour window as mandatory, not advisory. It gives you time to spot a broken include or a misaligned selector before DMARC starts acting on failures.

The most common failure I see pairs a strict SPF ending with a forwarding service. A record ending in -all tells receivers to reject anything outside the listed servers. Forwarding changes the sending IP, SPF fails, and if DKIM also fails alignment, DMARC rejects a legitimate message.

Why This Matters More Than Ever

On February 1, 2024, Gmail started requiring every sender to authenticate with SPF or DKIM. Bulk senders faced the full trio of SPF, DKIM, and DMARC. Google published the rules in its email sender guidelines, and the requirements have stayed in place since. This is permanent infrastructure now, not a campaign.

The numbers explain the push. Google reported that unauthenticated messages reaching Gmail users fell 75% after the authentication push, and Gmail blocks just under 15 billion unwanted emails every day.

Server room with rows of network racks and blinking status lights

Enforcement keeps tightening. Google states that starting November 2025, it ramps up enforcement on non-compliant traffic, with temporary and permanent rejections for messages that miss the requirements. Senders who treated the 2024 rules as optional now pay for it in rejected mail.

Yahoo applies the same bar: spam rates below 0.3%, DMARC at p=none or stricter, DKIM keys of at least 1024 bits, and unsubscribes honored within two days. The two biggest consumer mailbox providers now agree on the baseline, so one setup covers both.

Authentication is not reputation, and the distinction matters. SPF, DKIM, and DMARC prove identity. They say nothing about whether recipients want your mail. A domain with all three records in place and a 2% spam complaint rate still lands in spam. Keep the two ideas apart: authentication gets you through the door, and recipient behavior decides where you sit. Spoofing and phishing drive the authentication rules, while engagement drives placement.

SPF vs DKIM vs DMARC: The Comparison Table

Each protocol answers a different question. SPF asks whether the sending server has permission. DKIM asks whether the message stayed intact. DMARC asks what receivers should do when the first two answers come back no.

QuestionSPFDKIMDMARC
What it provesThe sending IP has permission to send for your domainThe message body and headers left your infrastructure untamperedThe From domain matches an authenticated domain, and failures get a policy
Where it livesTXT record at your domain rootTXT record at selector._domainkey, plus a signature header on each messageTXT record at _dmarc subdomain
What it stopsDirect spoofing from unauthorized serversContent tampering in transitImpersonation that slips past SPF or DKIM alone
What failure looks likePermerror when the record exceeds 10 DNS lookups, or fail when the IP is absentNo valid d= signature on the messagePolicy applied: none, quarantine, or reject
What it does not doIt does not cover third-party senders you forgot to list, and it breaks on forwardingIt does not tell receivers what to do with a failed messageIt does not authenticate anything on its own; it needs SPF or DKIM to pass first

Read the table as a chain. SPF and DKIM produce pass or fail results. DMARC consumes those results, checks alignment with the From domain, and applies your published policy. A domain with SPF alone gives receivers no instruction for a failure. A domain with DMARC alone has no authentication to enforce.

How SPF Works, and the 10-Lookup Limit That Bites

SPF lives in a TXT record at your domain root. A typical record reads v=spf1 include:_spf.google.com -all. The version tag comes first, each include: pulls in another domain’s authorized servers, and the ending qualifier sets the result for everything else. The -all ending means fail, ~all means soft fail, and +all means pass everything, which defeats the purpose. Never publish +all.

RFC 7208 defines the format and one hard limit that catches growing teams. SPF implementations must cap the number of lookup-causing terms at 10 per evaluation, and exceeding that cap returns permerror. The lookup-causing terms are include, a, mx, ptr, exists, and redirect. The RFC also recommends capping void lookups at two. A permerror result is worse than a clean fail: receivers treat it as a broken record and apply their own default handling.

Marketing platforms inflate this count fast. Each email service provider you add contributes an include:, and each of those includes can expand into more lookups at evaluation time. Three ESPs plus a CRM plus a support desk can push a record past 10 without anyone noticing, because the record itself looks short. Count lookups with a checker before you publish, not after delivery drops.

Two fixes handle an overflowing record. SPF flattening replaces each include: with the literal IP ranges it resolves to, which removes the lookups but freezes the list in place. You then own updates when a provider changes IPs. The redirect= mechanism points to a second record, which helps with delegation across subdomains. Pick one approach and document it, because a flattened record that nobody maintains rots within a year.

WordPress sites hit a related version of this problem. Contact form and newsletter mail often leaves through the hosting provider’s shared IP, which your SPF record never listed. The message fails SPF, and if DKIM also misses, DMARC applies your policy to your own mail. I check the sending path before I touch the record. If your site sends mail, read how to speed up a slow WordPress site and fix the mail path at the same time.

Self-hosted automation creates the same trap in a different shape. Notification email from a workflow tool leaves from your server IP, and each new integration adds another sender to track. If you run automation at home, self-hosting n8n with Docker Compose puts the mail path in your hands, which means the SPF record has to list it. Audit the record each time you add a sender.

How DKIM Signs Your Mail

DKIM adds a cryptographic signature to each outgoing message. Your mail server holds the private key and signs selected headers plus the body. The matching public key sits in DNS at selector._domainkey.yourdomain.com, where the selector is a name you choose, such as google or mail2026. A receiver fetches the public key, verifies the signature, and knows the message left your infrastructure intact. RFC 6376 defines the mechanism: responsibility is validated through the signature and a direct DNS query for the public key.

Key length sets the floor. Yahoo requires a minimum 1024-bit key, and most providers now generate 2048-bit keys by default. A 512-bit key from an old setup is a liability. Generate a fresh 2048-bit key pair when you set DKIM up, and rotate the selector on a schedule you can sustain. Rotation means publishing a new selector, switching signing to it, and removing the old public key after mail signed with it has cleared the queues. A stale selector left in DNS is harmless, while a missing selector breaks verification.

The d= tag in the signature carries the signing domain, and DMARC later checks it against the From domain. Alignment can be relaxed or strict. Relaxed alignment accepts a subdomain match, so mail signed for mail.example.com aligns with a From address at example.com. Strict alignment demands an exact match. Start relaxed. Strict alignment breaks the moment a subdomain sends mail you forgot to map.

DKIM survives forwarding in a way SPF cannot. Forwarding changes the sending IP and breaks SPF, but the DKIM signature travels with the message headers and body. As long as the forwarder leaves the signed content alone, the signature still verifies. That property makes DKIM the more reliable leg of the pair for domains with mailing lists and forwarding in the mix.

One caution applies to content. A forwarder that rewrites the subject line or appends a footer breaks the signature, because the body no longer matches what you signed. Mailing list software that adds footers is the usual culprit. Test a forwarded message end to end before you trust the setup.

How DMARC Turns Authentication Into Policy

DMARC is the policy layer. RFC 7489 defines it as a mechanism for policy distribution that enables stricter handling of messages that fail authentication, from no action through altered delivery up to rejection. The policy values are none, quarantine, and reject, set with the p= tag in a TXT record at _dmarc.yourdomain.com.

The rollout ladder is the whole strategy. Start at p=none, which tells receivers to take no action on failures but to send you aggregate reports. Move to quarantine once the reports show clean alignment. Move to reject once quarantine runs clean for a full reporting cycle. Each step needs evidence from the previous one. A domain that jumps straight to p=reject risks rejecting its own legitimate mail on the first day.

Aggregate reports arrive at the address in the rua= tag. These XML reports list every source that sent mail claiming your domain, with pass and fail counts per source. Read the first report before you tighten anything. It shows the senders you forgot: the old ESP, the HR tool, the printer that emails scans. Add each legitimate source to SPF or DKIM first, then move the policy.

Google documents the setup and the sequencing. Its DMARC setup guide states that DKIM and SPF should authenticate messages for at least 48 hours before DMARC goes live, and it gives a sample record: v=DMARC1; p=none; rua=mailto:[email protected], mailto:[email protected]; pct=100; adkim=s; aspf=s. The pct= tag controls what share of failing mail the policy covers, while adkim and aspf set alignment to strict or relaxed. The guide also states the pass rule: a message must pass SPF authentication with SPF alignment, or DKIM authentication with DKIM alignment.

Subdomains need attention. A DMARC record at the organizational domain does not cover subdomains unless you publish records for them or set a subdomain policy with sp=. Attackers spoof your existing subdomains, because receivers check the subdomain record first. Publish a DMARC record for each subdomain that sends mail, and set sp=reject on subdomains that never send mail at all.

Self-hosted mail deserves a warning here. A home mail server puts you in charge of every record, every key, and every report, with no provider to catch your errors. If you run infrastructure at home, read how to build a home server with a Raspberry Pi and treat mail as a separate project. Do not move to p=reject on a home setup until two full weeks of reports show zero legitimate failures.

Conclusion: Setup Order, Common Mistakes, and What to Do Next

Run the setup in dependency order. Publish SPF and list every sender, including the ones you forgot. Publish DKIM with a 2048-bit key and a selector you can rotate. Wait 48 hours and confirm both authenticate. Publish DMARC at p=none with a rua= address you monitor. Read two weeks of aggregate reports. Move to quarantine, then to reject, one step at a time.

Verify each step with a checker. Query the records with dig or an online SPF and DMARC checker, and confirm the results in Gmail Postmaster Tools under the compliance status for your domain. A record that looks right in your DNS panel can still fail evaluation because of a typo in an include or a missing semicolon. Trust the checker output, not the panel.

Five mistakes break production mail more than any others. A flattened SPF record that nobody updates. An include: chain that pushes past 10 lookups and returns permerror. A missing alignment between the From domain and the DKIM signing domain. A jump to p=reject before the reports come in. A forgotten subdomain that sends mail through a tool nobody documented. Check each one before you tighten the policy.

Two habits make the whole setup easier to maintain. Keep TLS current across your sending stack, because Gmail and Yahoo require a TLS connection for mail delivery. If your web server still needs a certificate workflow, you can set up Caddy with automatic HTTPS and remove certificate expiry from your list of worries. Treat authentication as part of security hygiene, not a one-time task. The same discipline that stops prompt injection in your AI tools applies here: verify the source, trust the check, and assume the attacker already tried.

Start today with the smallest safe step. Publish SPF, publish DKIM, wait 48 hours, then publish DMARC at p=none with a rua= address you read. Review the reports for two weeks, fix the senders you missed, and tighten one notch. Your domain stops being an easy spoof target the day the first report lands.

Irfan is a Creative Tech Strategist and the founder of Grafisify. He spends his days testing the latest AI design tools and breaking down complex tech into actionable guides for creators. When he’s not writing, he’s experimenting with generative art or optimizing digital workflows.

Leave a Reply

Your email address will not be published. Required fields are marked *

You might also like
Passkeys vs Passwords: Which Is More Secure?

Passkeys vs Passwords: Which Is More Secure?

How to Build a Home Server with a Raspberry Pi

How to Build a Home Server with a Raspberry Pi

Nginx Reverse Proxy for Docker: Practical Setup Guide

Nginx Reverse Proxy for Docker: Practical Setup Guide

How to Speed Up a Slow WordPress Site

How to Speed Up a Slow WordPress Site

GitHub Actions Cache: Cut CI Time and Cost

GitHub Actions Cache: Cut CI Time and Cost

Alembic Database Migrations in FastAPI: Production Guide

Alembic Database Migrations in FastAPI: Production Guide