DMARC, SPF and DKIM: Your Email Auth Is Probably Broken

DMARC, SPF and DKIM are the three DNS-based protocols that authenticate email and prevent domain spoofing. Most organizations publish these records but never enforce them. A DMARC policy stuck on p=none provides zero protection. SPF records that exceed 10 DNS lookups fail silently. DKIM keys left unrotated for years become a cryptographic liability. Fixing these three records is the single highest-impact change most IT teams can make to stop phishing at the perimeter.

What DMARC, SPF and DKIM Actually Do

These three protocols work together to answer one question: did this email actually come from the domain it claims to come from? Each protocol handles a different piece of the problem.

SPF (Sender Policy Framework)
A DNS TXT record that lists every IP address and mail server authorized to send email on behalf of your domain. When a receiving server gets an email claiming to be from your domain it checks this list. If the sending server is not on it the SPF check fails. Think of SPF as a guest list for your domain's outbound mail.
DKIM (DomainKeys Identified Mail)
A cryptographic signature attached to the header of every outgoing email. Your mail server signs each message with a private key. The corresponding public key is published in your DNS. The receiving server uses that public key to verify the signature was not tampered with in transit. DKIM proves the message was not altered after it left your infrastructure.
DMARC (Domain-based Message Authentication Reporting and Conformance)
A DNS TXT record that ties SPF and DKIM together and tells receiving servers what to do when authentication fails. DMARC adds two critical features: alignment checking (the domain in the From header must match the domain that passed SPF or DKIM) and reporting (receiving servers send you XML reports showing who is sending email using your domain).

Without all three working together you have gaps. SPF alone does not prevent header spoofing. DKIM alone does not tell receivers what to do with unsigned messages. DMARC without SPF and DKIM has nothing to evaluate. They are a system. Deploying one without the others is like installing a deadbolt but leaving the door frame rotted.

Why Most Implementations Are Broken

We audit email authentication configurations as part of nearly every engagement we handle. The failure rate is staggering. In our assessments over the past two years roughly 70 percent of organizations have at least one critical misconfiguration across their SPF, DKIM or DMARC records. Here are the patterns we see repeatedly.

DMARC Stuck on p=none

This is the most common problem by far. Organizations publish a DMARC record during an initial security project then never move past the monitoring phase. A p=none policy tells receiving mail servers to deliver messages even when authentication fails. It generates reports but blocks nothing. Your domain can be spoofed freely and the receiving server will deliver the spoofed message without hesitation.

The intent behind p=none is reasonable. You publish it first to collect data and identify all legitimate mail sources before enforcing. The problem is that nobody ever looks at the reports and the project stalls. We have seen p=none records that have been sitting untouched since 2019. Seven years of zero enforcement while attackers spoof the domain at will.

SPF Records Exceeding the DNS Lookup Limit

The SPF specification in RFC 7208 caps evaluation at 10 DNS lookups. Every include: mechanism triggers a lookup. Every a: and mx: mechanism triggers a lookup. Nested includes count toward the total. When you add your CRM platform and your marketing tool and your helpdesk and your HR system each one adds include statements. It adds up fast.

When an SPF record exceeds 10 lookups the entire check returns a PermError. That is not a soft fail. It is a hard failure that tells the receiving server the SPF record is broken. Some receivers treat PermError the same as a fail. Others ignore SPF entirely for that message. Either way your legitimate email is now in jeopardy and you probably have no idea because SPF evaluation errors do not generate bounce messages to the sender.

Missing Alignment

DMARC requires alignment between the domain in the visible From header and the domain that passed SPF or DKIM. Many organizations have SPF passing on a subdomain or a third-party service domain that does not align with their From header domain. The SPF check passes but DMARC alignment fails. The result is that DMARC evaluation fails even though the individual SPF and DKIM checks appear to succeed in isolation.

This is especially common with third-party senders. Your marketing platform sends email with a From address of notifications@yourdomain.com but the envelope sender is bounce@marketingplatform.com. SPF passes for the marketing platform's domain. DMARC alignment fails because the From domain does not match. Unless you also have DKIM signing with your domain's key on those messages DMARC will report a failure.

DKIM Keys Never Rotated

We routinely find DKIM keys that were generated when the mail system was first deployed and have not been touched since. Some are still using 1024-bit RSA keys which are considered weak by current standards. The NIST SP 800-57 guidance recommends 2048-bit RSA as the minimum for digital signatures. A 1024-bit DKIM key can be factored with sufficient compute resources. It is not a theoretical risk anymore.

Beyond key length the selectors themselves become stale. If an attacker obtains your private key through a breach or misconfiguration and you never rotate they can sign spoofed messages that pass DKIM indefinitely. Regular rotation limits the window of exposure.

How to Check Your Domain Right Now

You do not need special tools to audit your email authentication. Open a terminal and run these commands. Replace yourdomain.com with your actual domain.

Check Your SPF Record

nslookup -type=TXT yourdomain.com | grep "v=spf1"

You should see a single TXT record starting with v=spf1. If you see two SPF records that is a problem. The spec requires exactly one. Multiple SPF records cause a PermError. Count every include: mechanism and verify the total does not exceed 10 when you account for nested includes.

Check Your DMARC Record

nslookup -type=TXT _dmarc.yourdomain.com

Look at the p= value. If it says p=none your domain has no spoofing protection. The rua= tag should point to a mailbox you actively monitor. If rua is missing entirely you are not receiving aggregate reports and you are flying blind.

Check Your DKIM Record

nslookup -type=TXT selector._domainkey.yourdomain.com

Replace selector with your DKIM selector. Common selectors include google for Google Workspace, selector1 and selector2 for Microsoft 365, or a custom value set by your mail administrator. The response should contain a p= tag with your public key. If the key is 1024-bit (the base64-encoded public key is roughly 216 characters) you need to upgrade to 2048-bit.

The Most Common Mistakes We Find

After hundreds of email authentication audits these are the recurring failures ranked by frequency.

Mistake Impact How Common
DMARC at p=none for over 12 months Domain can be spoofed without restriction Very common
SPF record exceeds 10 DNS lookups SPF returns PermError; legitimate mail flagged Common
Multiple SPF TXT records published Entire SPF evaluation fails Common
No DKIM signing on third-party senders DMARC alignment fails for marketing and transactional email Very common
DKIM keys using 1024-bit RSA Weak key vulnerable to factoring Common
DMARC rua reports going to unmonitored mailbox No visibility into authentication failures Very common
SPF using +all or ~all instead of -all Soft fail or pass-all negates SPF protection Occasional
Subdomains without their own DMARC record Attackers spoof mail.yourdomain.com or hr.yourdomain.com Common

Step-by-Step Fix Guide

This is the process we walk clients through. It takes most organizations four to eight weeks to complete properly. Do not rush enforcement. A misconfigured DMARC reject policy will block your own legitimate email.

Step 1: Inventory All Mail Senders

Before you touch any DNS records you need a complete list of every system that sends email using your domain. This includes your primary mail platform (Microsoft 365 or Google Workspace), your CRM, your marketing automation tool, your helpdesk, your accounting system, your HR platform, your monitoring and alerting tools and any custom applications. Most organizations discover senders they forgot about during this step. Check your existing DMARC aggregate reports if you have them. They will show you every source of email claiming your domain.

Step 2: Fix Your SPF Record

Consolidate your SPF record into a single TXT record with no more than 10 DNS lookups. If you are over the limit you have a few options. First remove any include statements for services you no longer use. Second consider using SPF flattening which replaces include mechanisms with the actual IP addresses they resolve to. Be aware that flattened records need to be updated when the underlying IPs change. Third move some senders to use DKIM-only alignment with DMARC rather than relying on SPF.

Set your SPF record to end with -all (hard fail) rather than ~all (soft fail). Soft fail was a transitional mechanism that has outlived its usefulness. Hard fail tells receivers that any server not listed is definitively unauthorized.

Step 3: Deploy or Upgrade DKIM

Every mail sender in your inventory needs to sign outgoing messages with a DKIM key aligned to your domain. For your primary mail platform this is usually a configuration toggle. For third-party senders you will need to publish a DKIM key they provide in your DNS and enable signing in their platform settings.

Use 2048-bit RSA keys at minimum. Publish each key under a unique selector that identifies the sending service (for example crm._domainkey.yourdomain.com or marketing._domainkey.yourdomain.com). This makes it straightforward to rotate individual keys without affecting other senders.

Step 4: Publish DMARC at p=none and Monitor

If you do not have a DMARC record yet publish one now.

v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com; ruf=mailto:dmarc-forensics@yourdomain.com; fo=1

The rua tag is for aggregate reports. The ruf tag is for forensic (failure) reports. The fo=1 flag requests forensic reports for any authentication failure not just alignment failures. Actually read these reports. Use a DMARC report analyzer if the raw XML is too dense. You are looking for legitimate senders that are failing authentication so you can fix them before enforcing.

Step 5: Move to p=quarantine

After two to four weeks of monitoring with no legitimate senders failing authentication move to p=quarantine. This tells receiving servers to send failing messages to spam rather than delivering them to the inbox. Use the pct= tag to ramp up gradually. Start with pct=10 (apply quarantine to 10 percent of failing messages) and increase over time as you confirm no legitimate mail is being affected.

v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@yourdomain.com; ruf=mailto:dmarc-forensics@yourdomain.com; fo=1

Step 6: Enforce with p=reject

Once you have been at p=quarantine; pct=100 for at least two weeks with clean reports move to p=reject. This is the final state. Receiving servers will reject any message that fails DMARC authentication outright. It will not be delivered. It will not go to spam. It will be dropped.

v=DMARC1; p=reject; rua=mailto:dmarc-reports@yourdomain.com; ruf=mailto:dmarc-forensics@yourdomain.com; fo=1

Also publish a DMARC record for your subdomains. If you do not use subdomains for email add sp=reject to your organizational DMARC record. This prevents attackers from spoofing anything.yourdomain.com even if that subdomain does not exist.

Step 7: Set a Rotation Schedule

Put DKIM key rotation on your calendar. Every six months at minimum. Document the rotation procedure so it does not depend on a single person's knowledge. The process is: generate a new key pair, publish the new public key under a new selector in DNS, configure the mail server to sign with the new key, wait 48 hours for DNS propagation, verify DKIM is passing with the new selector, then remove the old selector from DNS after a grace period.

Subdomain Protection

Attackers know that most organizations only protect their root domain. If your DMARC record is on _dmarc.yourdomain.com but you have no record on _dmarc.mail.yourdomain.com or _dmarc.hr.yourdomain.com those subdomains inherit the organizational policy. That is fine if your organizational policy is p=reject. But if it is p=none every subdomain is also unprotected.

For subdomains you do not use for email publish an SPF record of v=spf1 -all and a DMARC record of v=DMARC1; p=reject. This explicitly tells the world that no email should ever come from those subdomains.

Frequently Asked Questions

What happens if my DMARC policy is set to p=none?

A DMARC policy of p=none tells receiving mail servers to take no action when authentication fails. Spoofed emails using your exact domain will still be delivered to recipients. The p=none setting is intended as a monitoring phase only. Staying on p=none permanently means your domain has no spoofing protection. You should move to p=quarantine and then p=reject after reviewing your DMARC aggregate reports. CISA's BOD 18-01 mandated DMARC enforcement for all federal agencies back in 2018.

How many DNS lookups can an SPF record have?

The SPF specification (RFC 7208) limits SPF records to 10 DNS lookups. Each include, a, mx, ptr and redirect mechanism counts as one lookup. Nested includes count toward the total. Exceeding 10 lookups causes a PermError which means the entire SPF check fails. Your legitimate email may be rejected or flagged as suspicious and you will not receive a bounce notification about it.

How often should DKIM keys be rotated?

Rotate DKIM keys at least every 6 to 12 months. Keys using 1024-bit RSA should be upgraded to 2048-bit immediately. Rotation involves publishing a new key in DNS under a new selector, configuring your mail server to sign with the new key and keeping the old key published for a transition period so in-flight messages can still be verified. The NIST SP 800-57 key management guidelines provide the authoritative framework for key lifecycle management.

External Resources

Free Security Scorecard Email Header Analyzer Tabletop Exercises