Skip to content
Back to Blog
DNS & Networking11 min read

SPF DKIM DMARC Setup: 7 Fixes That Actually Work

Configure SPF, DKIM, and DMARC records correctly to stop your emails landing in spam, plus how to read DMARC reports and fix authentication failures.

Written by Abdul AbrorTechnical Hosting Support Engineer
SPF DKIM DMARC Setup: 7 Fixes That Actually Work
On this page

Your transactional emails are landing in spam. Customer notifications never arrive. Password resets vanish into the void. The cause is almost always broken email authentication—specifically SPF, DKIM, and DMARC records that are either missing, misconfigured, or contradicting each other.

I've handled hundreds of support tickets where a single extra character in an SPF record or a missing DKIM selector destroyed email deliverability for an entire domain. The fix is straightforward once you understand what each record actually does and how receiving mail servers interpret them together.

What SPF, DKIM, and DMARC actually do

These three DNS records work as a team to prove your emails are legitimate.

SPF (Sender Policy Framework) lists which IP addresses and mail servers are allowed to send email for your domain. It's a TXT record at your root domain that receiving servers check against the connecting IP.

DKIM (DomainKeys Identified Mail) adds a cryptographic signature to every outgoing email. The receiving server fetches your public key from DNS and verifies the signature matches. If the message was altered in transit, the signature breaks.

DMARC (Domain-based Message Authentication, Reporting and Conformance) ties SPF and DKIM together and tells receiving servers what to do when authentication fails. It also sends you daily reports showing who's sending email using your domain—legitimate servers and spoofing attempts alike.

Without all three, modern mail providers treat your messages with suspicion. Gmail, Outlook, and Yahoo now require DMARC for bulk senders, and even transactional email benefits from proper authentication.

Setting up SPF correctly

An SPF record is a single TXT record at your domain root. Here's a basic example:

v=spf1 mx a ip4:203.0.113.50 include:_spf.google.com ~all

Breaking that down:

  • v=spf1 declares the SPF version
  • mx authorizes servers listed in your MX records
  • a authorizes the IP of your A record
  • ip4:203.0.113.50 authorizes a specific IPv4 address
  • include:_spf.google.com imports Google Workspace's SPF record
  • ~all is a soft fail for everything else

The ending matters. Use -all for a hard fail (strict), ~all for soft fail (lenient), or ?all for neutral (not recommended). I use ~all during initial setup to avoid blocking legitimate mail if I missed an IP, then switch to -all once I've verified everything works.

Common SPF mistakes:

  • Multiple SPF records (only one is allowed; combine them)
  • More than 10 DNS lookups (each include: and mx counts toward the limit)
  • Listing individual IPs when an include: would cover them
  • Forgetting your web host's mail server IPs

Check your current SPF with dig:

dig +short TXT yourdomain.com | grep spf1

Or use an online SPF validator to count your DNS lookups. If you hit the 10-lookup limit, flatten your SPF record by replacing include: statements with the actual IP ranges they reference.

Configuring DKIM signatures

DKIM requires generating a keypair, publishing the public key in DNS, and configuring your mail server to sign outgoing messages with the private key.

Most cPanel servers use the built-in DKIM manager. Navigate to Email Deliverability in WHM, click the domain, and enable DKIM. cPanel generates a 2048-bit key and creates the DNS record automatically if you're using local nameservers.

The DNS record looks like this:

default._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

The default part is the selector. You can use any selector name, and you can have multiple selectors active at once (useful when rotating keys or testing). The long p= string is your public key.

For external mail services:

If you send through Mailgun, SendGrid, Amazon SES, or similar, they'll provide DKIM records for you. Add them exactly as specified, including the selector. A common pattern:

k1._domainkey.yourdomain.com CNAME k1.domainkey.mailgunprovider.com

Some providers use CNAME records pointing to their infrastructure instead of publishing the full key in your DNS. Either approach works.

Testing DKIM:

Send a test email to a Gmail address you control, open the message, click "Show original," and look for DKIM: 'PASS' in the authentication results header. If it shows FAIL or neutral, your DNS record isn't propagating or the selector is wrong.

You can also verify the DNS record directly:

dig +short TXT default._domainkey.yourdomain.com

Make sure the selector name matches what your mail server is actually using. I've seen tickets where someone changed the selector in cPanel but forgot to update the sending configuration.

Building a DMARC policy

DMARC is where you declare your authentication policy and set up reporting. Start with monitoring mode, read the reports for a few weeks, then tighten the policy once you've fixed any issues.

Here's a monitoring-only DMARC record:

_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; pct=100; adkim=r; aspf=r"

Breaking down the tags:

  • v=DMARC1 is the version
  • p=none means no action (monitoring only)
  • rua=mailto: sets where aggregate reports go (daily XML summaries)
  • ruf=mailto: sets where forensic reports go (individual failure samples)
  • pct=100 applies the policy to 100% of messages
  • adkim=r uses relaxed DKIM alignment
  • aspf=r uses relaxed SPF alignment

Alignment is the key concept. For SPF to pass DMARC, the domain in the From: header must match the domain that passed SPF (relaxed allows subdomains). Same for DKIM.

Once you've confirmed your legitimate mail passes, upgrade the policy:

_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:[email protected]; adkim=s; aspf=s"

The p=quarantine policy tells receivers to send failing messages to spam. When you're confident everything is clean, use p=reject to block them entirely.

Change adkim=s and aspf=s to strict alignment once you've verified your From: domains match exactly. Strict alignment is more secure but can break email if you have complicated sending scenarios.

Reading DMARC reports

Aggregate reports arrive daily as gzipped XML files attached to emails sent to your rua= address. They're barely human-readable in raw form.

A typical report includes:

  • Source IP addresses sending mail claiming to be from your domain
  • Volume of messages from each IP
  • SPF and DKIM results
  • The policy applied

You'll see entries for your own mail servers, your ESP, any third-party services that send on your behalf, and spoofing attempts. In support tickets I handled, the usual surprise was forgotten services—an old marketing automation tool still sending newsletters, a CRM integration nobody remembered setting up, or a WordPress site using the server's local mail.

Tools for parsing reports:

Use a DMARC report analyzer instead of reading XML by hand. Free options include dmarcian's analyzer, Postmark's DMARC monitor, and self-hosted solutions like parsedmarc. These services accept forwarded reports or connect via IMAP to fetch them automatically.

Look for sources with DMARC fail results. If the IP belongs to your infrastructure but fails SPF, add it to your SPF record. If it fails DKIM, check that your selector is configured correctly. If it's a spoofing attempt (some random IP in a foreign country sending thousands of messages), your DMARC policy will eventually block them once you move past p=none.

Fixing common authentication failures

So what if the port is open but authentication still fails?

SPF failures:

  • The sending IP isn't listed in your SPF record (add it)
  • Your SPF record has a syntax error (validate it)
  • You're forwarding email, which breaks SPF (use SRS if possible)
  • The From: domain doesn't match the envelope sender (DMARC alignment issue)

DKIM failures:

  • The selector doesn't exist in DNS (check your mail server config)
  • The signature is broken (key mismatch between DNS and mail server)
  • The message was modified in transit (mailing list software often does this)
  • The selector or domain name has a typo

DMARC failures even when SPF or DKIM pass:

  • Alignment is the problem; the domains don't match
  • You're using strict alignment but sending from a subdomain
  • Your ESP signs with their domain, not yours (request a custom DKIM setup)

Run dmarcian's SPF survey tool to see which IPs are actually sending mail for your domain according to DMARC reports. Compare that list to your SPF record.

Seven fixes that actually work

  1. Combine multiple SPF records into one. DNS returns them in random order and mail servers only check the first they see.

  2. Keep SPF under 10 lookups. Flatten it by replacing include: statements with IP ranges, or use SPF macro tricks for complex setups.

  3. Use separate DKIM selectors for each sending service. This lets you rotate keys without breaking everything and makes report analysis clearer.

  4. Start DMARC at p=none and wait two weeks before tightening. You'll discover forgotten services in the reports.

  5. Set up a dedicated email address for DMARC reports. They're noisy and you don't want them mixed with regular mail. Use a forwarder if your main domain can't receive mail directly.

  6. Fix alignment issues by making the From: domain match your authenticated domain. If you're sending transactional email through an ESP, use a subdomain like mail.yourdomain.com for the From: address and publish SPF/DKIM for that subdomain.

  7. Check your reports weekly until you reach p=reject. New services get added, IPs change, and you need to keep your records current.

The subdomain question

Your DMARC policy at _dmarc.yourdomain.com applies to all subdomains unless they have their own DMARC record. This is usually what you want. But if you send high-volume email from a subdomain like news.yourdomain.com, give it its own SPF, DKIM, and DMARC records.

Example:

news.yourdomain.com TXT "v=spf1 include:_spf.mailgunprovider.com ~all"
k1._domainkey.news.yourdomain.com CNAME k1.domainkey.mailgunprovider.com
_dmarc.news.yourdomain.com TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

This isolates your newsletter authentication from your main domain. If the newsletter tool misconfigures something, your transactional email keeps working.

Questions about SPF, DKIM, and DMARC

Q: Can I have both an SPF record and a DMARC record?
You need both. SPF and DMARC serve different purposes and receiving servers check them separately. DMARC builds on SPF and DKIM; it doesn't replace them.

Q: What happens if I set p=reject and my SPF record is incomplete?
Legitimate mail gets blocked. Always start with p=none, fix everything the reports show, move to p=quarantine for a few weeks, then go to p=reject.

Q: Do I need DKIM if I already have SPF?
Yes. SPF only validates the sending server; DKIM validates the message content itself and survives forwarding better. You need both for reliable DMARC.

Q: Why do my DMARC reports show failures from legitimate services?
Either those services aren't included in your SPF record, or they're not signing with DKIM, or there's an alignment mismatch. Check which authentication method failed and fix that record.

Q: How long does DNS propagation take for email records?
Usually under an hour for most resolvers, up to 24 hours for stragglers. The TTL you set controls caching, but you can't force all resolvers to respect it.

Q: Can DMARC reports contain sensitive information?
Forensic reports (ruf=) can include message samples. Aggregate reports (rua=) only contain metadata. If you're handling sensitive data, either don't request forensic reports or encrypt them.

What to check first when email breaks

Authentication problems show up in bounce messages, spam complaints, and silent delivery failures. Before touching DNS, send a test email to [email protected] or a similar service that replies with a full authentication report. That'll tell you exactly which record is broken.

Once you know the culprit, verify the DNS record is published correctly with dig, wait for propagation, then test again. Most issues come down to typos, forgotten IPs, or alignment mismatches—not exotic edge cases.

Keep your DMARC reports flowing and review them monthly even after everything works. Services change, your infrastructure evolves, and attackers constantly probe for weak authentication. The reports tell you what's actually happening instead of what you think is happening.