Guide
One merged SPF record, a DKIM key that really signs, DMARC from p=none to quarantine, and the two failures that break most setups: duplicate SPF records and a guessed Microsoft DKIM target.
Authentication is pass or fail. Since Google and Yahoo's bulk-sender rules took effect, a sender who misses it is rejected or junked before content is considered, and no amount of warm-up compensates. The good news is that only three records matter and each has one correct shape.
This is the configuration our DNS engine writes and verifies automatically, documented for anyone who wants to write it by hand. It includes the two failures that account for most of the broken setups we have seen in production, both of which look fine in a registrar dashboard.
1
SPF
One TXT record on the domain apex listing who may send for you. Two records is an automatic permanent failure. Ends with ~all. Costs a DNS lookup per include, and the eleventh lookup fails the whole thing.
2
DKIM
A cryptographic signature on every message, published as a TXT or CNAME record on a selector the provider names. Verify that the provider reports signing, not merely that the record exists.
3
DMARC
A TXT record on _dmarc telling receivers what to do when SPF and DKIM fail alignment, and where to send reports. Start at p=none, watch two weeks, then tighten.
SPF lists the servers allowed to send for your domain. The fatal mistake is publishing two SPF TXT records on the same host. That is not a warning or a partial pass; it is a permanent error, and a permanent error means the receiving system cannot evaluate SPF at all. It happens constantly, because one record arrives with the website host and another with the mail provider, and both look correct on their own.
Merge instead. One record, one v=spf1, every include in it. Microsoft 365 uses include:spf.protection.outlook.com. Google Workspace uses include:_spf.google.com. A self-hosted server uses an a: or ip4: for the host that actually sends. End with ~all rather than -all on a sending domain: a soft fail leaves room for the forwarding paths that legitimately break SPF, and receivers weigh DMARC alignment more heavily anyway.
Then watch the ten-lookup limit. Every include, a, mx, ptr, exists and redirect mechanism costs a DNS lookup, includes nest, and the eleventh lookup produces the same permanent error as a duplicate record. A chain that worked with one provider silently breaks when you add a second. We have had three live domains fail this way at once, all of them showing a valid-looking record in the registrar UI, with the count only visible when a resolver walked the whole chain. Count the lookups, flatten where you can, and re-check after every provider change.
DKIM signs each message with a private key the provider holds, and receivers check it against a public key you publish. It is the only one of the three that survives forwarding intact, which is why DMARC alignment usually rests on it rather than on SPF.
Google Workspace generates a 2048-bit key in the Admin console, under Apps, Google Workspace, Gmail, Authenticate email. Generate it, publish the TXT record it shows, then come back and press start authentication. A published key with authentication never started signs nothing, and the Admin console will tell you so if you look.
Microsoft 365 is where the common mistake lives. The two CNAME records on selector1._domainkey and selector2._domainkey point at a host inside your tenant's onmicrosoft.com domain, and that host is not the pattern most guides print. The target includes a per-tenant ring letter, and tenants differ, so a CNAME copied from a blog post or from another tenant resolves to nothing and DKIM quietly never signs. Read the exact target from the Microsoft 365 Defender portal or from PowerShell for the tenant you are configuring. Never guess it, and never reuse the value from a tenant you set up last month.
Whichever provider you use, verify that it reports signing rather than record present. Those are different states, and only one of them puts a d= header on your mail.
DMARC tells receivers what to do when SPF and DKIM fail alignment, and gives you reports about who is sending as you. Start with v=DMARC1; p=none; rua=mailto:reports@yourdomain.com. At p=none nothing legitimate is lost while you read the reports and find the sending sources you forgot about.
Alignment is the part that surprises people. SPF alignment requires the Return-Path domain to match the From domain, and many platforms send with their own Return-Path by default, which passes SPF while failing DMARC. DKIM alignment requires the d= domain in the signature to match the From domain. One of the two must align. Check a real received message rather than a test tool, because the test tool sends from a path your campaigns do not use.
After two clean weeks, move to p=quarantine. For dedicated cold-sending domains, p=reject adds little beyond quarantine and can bite legitimate forwarding, so quarantine is the pragmatic destination. Your primary corporate domain is a different matter and should eventually reach reject, but that is a separate project with a longer list of sending sources to find.
Skipping DMARC entirely is no longer an option. Google and Yahoo both require it from bulk senders, alongside a one-click unsubscribe and a spam-complaint rate held below 0.3 percent, with 0.1 percent as the number to actually aim for.
A sending domain needs MX records even if no human ever reads that mailbox. Without them the domain cannot receive bounces, out-of-office replies or the actual replies you are sending to get, and a domain that cannot receive mail is a signal in its own right. Point MX at whichever provider hosts the mailbox.
If you track opens or clicks, publish a tracking subdomain and use it. A redirect through a shared tracking host puts another sender's reputation inside your message, and link reputation is weighed almost as heavily as sending reputation. The same applies to any reply subdomain your platform uses.
Add a postmaster or abuse address and an entry for it if your provider expects one. It takes a minute and it is the difference between a receiving network telling you about a problem and a receiving network simply dropping you.
A registrar dashboard shows what you saved. A mailbox provider sees what public resolvers serve. Those are different things, and the gap between them is where most silent failures live: a record saved on the wrong host, a zone that did not reload, a CNAME flattened by a proxy, an apex record that the registrar rewrote.
After writing each record, query a public resolver directly. dig TXT yourdomain.com @1.1.1.1 for SPF, dig TXT selector._domainkey.yourdomain.com for DKIM, dig TXT _dmarc.yourdomain.com for DMARC. Only trust a record once a resolver outside your own account returns it. Propagation runs from minutes to hours.
We treat a record as unverified until that public proof comes back, and a domain as unable to send until all of its records are verified. The discipline matters more than the tooling: almost every authentication incident we have investigated was a record someone had written, seen in a dashboard, and never confirmed from the outside.
Authentication failures rarely announce themselves as authentication failures. They arrive as rejections with a 5.7.x code, and the most useful habit in cold email is reading that family correctly. A 5.1.1 means the address does not exist and is about the recipient. A 5.7.x means the receiving system examined your domain, your IP or your authentication and declined, and is about you.
Common ones: 5.7.26 is an explicit authentication failure at Google, usually DKIM not signing or SPF failing alignment. 5.7.1 is a policy rejection, often DMARC. A permanent error in the SPF evaluation itself shows up as a permerror in the headers rather than in the bounce text, which is why the ten-lookup problem goes unnoticed for so long.
The rule that follows: never suppress a recipient because of a 5.7.x. The recipient did nothing wrong, and suppressing them quietly destroys a list while the actual fault stays in place. Suppress or pause the sending domain instead, fix the record, verify it against a public resolver, and resume.
DKIM before DMARC, always. Enforcing a policy on top of a signature that is not yet signing is how a working domain stops delivering.
Yes. Google and Yahoo's bulk-sender requirements make SPF and DKIM mandatory and DMARC required at any volume that matters, and receivers apply the same logic well below the formal bulk threshold. Treat all three as launch blockers.
Three causes cover almost all of it: two SPF records on the same host, which is an automatic permanent error; more than ten DNS lookups in the include chain, which is the same error by a slower route; or the record published on the wrong host, typically a subdomain instead of the apex. Check with a public resolver rather than the registrar interface.
Eventually, for your primary corporate domain. For dedicated cold-sending domains, p=none then p=quarantine after two clean weeks is the pragmatic path. Reject adds little over quarantine for a domain that only sends campaigns, and it punishes legitimate forwarding.
Almost always because the CNAME target was guessed rather than read. The host inside your tenant's onmicrosoft.com domain includes a per-tenant ring letter, and the pattern printed in most guides does not match every tenant. Read the exact target from the Defender portal or PowerShell for that specific tenant.
Each domain needs its own record on its own apex, but they can be identical if every domain sends through the same provider. What you cannot do is point them all at one domain through an include and forget the lookup count; every nested include costs a lookup on every domain.
Alignment requires the domain in the Return-Path (for SPF) or the d= signature (for DKIM) to match the visible From domain. Many platforms send with their own Return-Path, which passes SPF for their domain and fails alignment for yours. DKIM alignment is the more reliable of the two because it survives forwarding.
Minutes to hours to propagate, and one message to prove. Send a real message to a mailbox you control at a different provider and read the Authentication-Results header. A test tool proves the record; a real message proves the path.
No. emailcampaign.ai writes these records through your registrar behind one approval, reads DKIM targets from the tenant rather than guessing them, and flips a record to verified only when a public resolver returns it. The same discipline works by hand; it just has to be done every time.
The platform writes and verifies these exact records through your registrar, behind one approval.
Free to start · no card required · one approval builds the fleet