

Email authentication is misconfigured far more often than most people realize. The number of domains that get it right on the first attempt is shockingly low.
Here is the reality: 84% of domains still do not have a DMARC record. Of the 16% that do, a significant chunk are stuck on p=none, which does effectively nothing. Gmail and Yahoo started enforcing authentication requirements in February 2024. If you are sending transactional email without proper SPF, DKIM, and DMARC, you are already losing messages to spam.
This guide walks you through setting up all three correctly, in the right order, with real DNS record examples.
Email Authentication Adoption Rates (2026)
What You Will Learn
- How SPF, DKIM, and DMARC work together
- Exact DNS records to create for each protocol
- Common mistakes that silently break email delivery
- How to test and validate your configuration
- The correct progression from
p=nonetop=reject
Step 1: Set Up SPF (Sender Policy Framework)
SPF tells receiving mail servers which IP addresses are authorized to send email on behalf of your domain. It is a single TXT record on your root domain.
The DNS Record
example.com. IN TXT "v=spf1 include:_spf.transactional.so include:_spf.google.com -all"Breaking this down:
v=spf1-- version identifier, must come firstinclude:_spf.transactional.so-- authorizes Transactional's sending IPsinclude:_spf.google.com-- authorizes Google Workspace (if you use it)-all-- reject everything else (hard fail)
Common SPF Mistakes
Too many DNS lookups. SPF has a hard limit of 10 DNS lookups. Every include, a, mx, and redirect counts as a lookup. Nested includes count too. SPF records with 15+ lookups silently fail because mail servers stop processing after 10.
Check your lookup count:
# Count SPF lookups
dig +short TXT example.com | grep spf
# Use an online tool to validate
# mxtoolbox.com/spf.aspxUsing ~all instead of -all. Soft fail (~all) was a reasonable default in 2015. In 2026, use hard fail (-all). Soft fail tells receivers "this might be unauthorized but let it through anyway." That defeats the purpose.
Multiple SPF records. You can only have one SPF TXT record per domain. If you have two, both are invalid. This commonly happens when someone adds a new email provider without checking what already exists.
# WRONG - two SPF records
example.com. IN TXT "v=spf1 include:_spf.google.com -all"
example.com. IN TXT "v=spf1 include:_spf.transactional.so -all"
# CORRECT - single combined record
example.com. IN TXT "v=spf1 include:_spf.google.com include:_spf.transactional.so -all"Step 2: Set Up DKIM (DomainKeys Identified Mail)
DKIM adds a cryptographic signature to every outgoing email. The receiving server checks this signature against a public key published in your DNS. If the signature matches, the email has not been tampered with in transit.
Generate Your DKIM Keys
Most email providers generate DKIM keys for you. In Transactional, navigate to Settings > Domains > Your Domain > DKIM and we generate a 2048-bit RSA key pair. You will get a DNS record to publish.
The DNS Record
DKIM records go on a subdomain using a selector:
transactional._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1234...long-public-key...5678"Breaking this down:
transactional-- the selector (identifies which key to use)_domainkey-- required subdomainv=DKIM1-- versionk=rsa-- key typep=-- the public key (base64 encoded)
Common DKIM Mistakes
Key too long for a single TXT record. DNS TXT records have a 255-character string limit. For 2048-bit keys, you need to split the value across multiple strings within a single record:
transactional._domainkey.example.com. IN TXT (
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA"
"the-rest-of-the-key-here..."
)Most DNS providers handle this automatically, but some cheap registrar DNS panels do not. If DKIM verification fails immediately after setup, this is usually why.
Never rotating keys. DKIM keys should be rotated at least once a year. The process: generate a new key pair with a new selector, publish the new public key, update your email provider to sign with the new key, wait 48 hours, then remove the old public key record.
# Verify DKIM is published correctly
dig +short TXT transactional._domainkey.example.comStep 3: Set Up DMARC
DMARC ties SPF and DKIM together with a policy. It tells receiving servers what to do when authentication fails and where to send reports.
Start with p=none
Always start with a monitoring-only policy:
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensics@example.com; pct=100"p=none-- do not take action on failures, just reportrua=-- aggregate report destination (daily XML reports)ruf=-- forensic report destination (per-failure reports)pct=100-- apply policy to 100% of messages
Reading DMARC Reports
The aggregate reports (rua) come as XML files, usually daily. They look like this:
<record>
<row>
<source_ip>198.51.100.1</source_ip>
<count>1523</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
</record>You want to see dkim=pass and spf=pass for all your legitimate sending sources. Any failures from your own IPs mean your SPF or DKIM is misconfigured.
Use a DMARC report analyzer service rather than parsing XML by hand. Services like Postmark's DMARC Digests or dmarcian make this much easier.
The Progression: none to quarantine to reject
After 2-4 weeks on p=none, once you have confirmed all legitimate sources pass authentication:
Week 4-6: Move to quarantine at 10%
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=10; rua=mailto:dmarc-reports@example.com"Week 6-8: Increase to quarantine at 50%
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=50; rua=mailto:dmarc-reports@example.com"Week 8-10: Full quarantine
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc-reports@example.com"Week 12+: Move to reject
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com"Do not rush this. Companies that jump straight to p=reject often end up blocking their own marketing emails, support ticket notifications, and automated alerts. The gradual rollout exists for a reason.
Step 4: Validate Everything
Quick Validation Commands
# Check SPF
dig +short TXT example.com | grep "v=spf1"
# Check DKIM
dig +short TXT transactional._domainkey.example.com | grep "v=DKIM1"
# Check DMARC
dig +short TXT _dmarc.example.com | grep "v=DMARC1"Send a Test Email
Send an email to a Gmail account and check the headers. Look for:
Authentication-Results: mx.google.com;
dkim=pass header.d=example.com;
spf=pass (google.com: domain of test@example.com designates 198.51.100.1 as permitted sender);
dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com
All three should show pass. If any show fail or neutral, go back and fix the corresponding DNS record.
Online Tools
- MXToolbox -- comprehensive DNS and email diagnostics
- mail-tester.com -- send an email and get a deliverability score
- Google Postmaster Tools -- ongoing deliverability monitoring for Gmail
- dmarcian -- DMARC report analysis and monitoring
DMARC Alignment: The Detail Most People Miss
DMARC requires alignment between the domain in the From header and the domains authenticated by SPF and DKIM. There are two alignment modes:
- Relaxed (default): The organizational domain must match.
mail.example.comaligns withexample.com. - Strict: The exact domain must match.
mail.example.comdoes NOT align withexample.com.
# Explicit relaxed alignment (default)
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; aspf=r; adkim=r; rua=mailto:dmarc@example.com"
# Strict alignment
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; aspf=s; adkim=s; rua=mailto:dmarc@example.com"Start with relaxed. Only move to strict if you have a specific security requirement.
Subdomain Policies
If you send email from subdomains (e.g., notifications.example.com), you need to handle subdomain policies:
# Main domain policy
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=quarantine; rua=mailto:dmarc@example.com"The sp=quarantine sets a separate policy for subdomains. You can also create DMARC records on individual subdomains for more granular control.
Checklist
Before you move on:
- Single SPF record with 10 or fewer DNS lookups, ending in
-all - DKIM key published and verified with
dig - DMARC record starting at
p=nonewithruafor reports - Test email to Gmail showing all three passing in headers
- DMARC reports flowing and reviewed weekly
- Plan to progress from
p=nonetop=rejectover 8-12 weeks
What Comes Next
Email authentication is table stakes in 2026. Every domain sending transactional email needs SPF, DKIM, and DMARC configured correctly. The setup takes about 30 minutes if you follow the steps above. The monitoring and progression to p=reject takes 8-12 weeks.
If you are using Transactional for email delivery, we generate and manage your DKIM keys automatically and provide guidance on SPF and DMARC records during domain verification. But regardless of which provider you use, the DNS records follow the same standards.
Get these three records right and you eliminate the most common reason transactional emails end up in spam.
Sources & References
Related Posts

From 78% to 99.5% Inbox Placement. One SaaS Team's Email Fix.
How a B2B SaaS sending 2M transactional emails per month went from 78% inbox placement to 99.5% in 6 weeks by fixing authentication, IP reputation, and sending practices.

15 Years of Shipping Software Taught Me Email Deliverability is an Infrastructure Problem
Why developers treat email as an afterthought and what goes wrong at scale. IP warming, feedback loops, bounce handling, reputation management, and the architecture of a reliable email pipeline.

Stop Writing Raw HTML Emails. Use React Email Templates Instead.
Build maintainable, responsive email templates using React Email instead of struggling with raw HTML tables. Includes password reset and order confirmation examples.
YOUR AGENTS DESERVE
REAL INFRASTRUCTURE.
START BUILDING AGENTS THAT DO REAL WORK.