The ticket arrived as a deliverability complaint. A department at contoso.com sent its newsletters and public notices through a marketing-email platform — call it Larkspur (anonymized) — and the mail was reliably landing in recipients' junk folders. Larkspur's own deliverability team had sent a notice that said, in effect: your domain is not authenticated; set up DKIM signing and a DMARC record.
That notice is where most of these go sideways. Taken at face value it tells you to bolt on authentication the domain supposedly lacks. But before touching a single DNS record, the first job is to check whether the claim is even true for this domain. It wasn't — and the gap between what the notice said and what was actually live is the whole lesson.
01First move: verify the claim against live DNS
Deliverability notices are boilerplate. The zone is ground truth.
Pulling the live records showed a domain that was already well-authenticated — not a bare one:
contoso.com TXT "v=spf1 include:spf.protection.outlook.com ~all" _dmarc.contoso.com TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:...; fo=1" selector1._domainkey CNAME selector1-contoso-com._domainkey.contoso.onmicrosoft.com selector2._domainkey CNAME selector2-contoso-com._domainkey.contoso.onmicrosoft.com s1._domainkey CNAME s1.domainkey.u-transactional-svc.example.net s2._domainkey CNAME s2.domainkey.u-transactional-svc.example.net
So the domain had SPF, it had DMARC set to quarantine (enforcing, not just monitoring), and it had two independent DKIM signers already published: Microsoft 365 (the selector1/2 records) and a separate transactional-email service used for receipts and system notifications (the s1/s2 records). The notice's line about "no DMARC record" was simply generic template text that didn't apply here.
Mental model
A vendor deliverability notice is a form letter, not a diagnosis. It's written for the worst-case customer with nothing configured. Read it as "something in your authentication doesn't cover our mail" — then go find out what — not as a literal to-do list.
Which raises the real question. If DKIM already works for two senders, why does a third sender's mail fail? The domain is clearly capable of DKIM. The instinct is to think authentication is a property of the domain — switch it on once and every sender is covered. That instinct is exactly wrong, and it's why this case is worth writing down.
02The thing nobody internalizes: DKIM is per-sender
One domain, many independent signers — each with its own key.
DKIM doesn't authenticate a domain. It authenticates a stream of mail from one sending service. Each service that sends on your behalf gets its own selector — a label under _domainkey — pointing at that service's public key. The service holds the matching private key and signs the mail it sends; the receiver fetches the public key at the selector named in the signature and checks it. Different service, different selector, different key. They don't share, and one cannot cover another.
Seen this way the failure is obvious. Larkspur was sending mail as contoso.com but had no key published under the domain's _domainkey. The existing selectors belonged to M365 and the transactional service and could not sign Larkspur's mail. So every newsletter left the building unsigned as far as the domain was concerned.
03Why unsigned means junked — and why SPF can't save it
Follow the alignment, and the quarantine policy does the rest.
An unsigned-for-the-domain message runs straight into DMARC. DMARC passes only if at least one of SPF or DKIM both passes and aligns with the visible From: domain. Walk the two paths for Larkspur's mail:
This is also why you don't fix this by editing SPF. The tempting move is to add Larkspur to the SPF record. It won't help: bulk platforms send with their own envelope return-path, so SPF authenticates their domain. DMARC requires the passing mechanism to align with the visible From domain, and a return-path of larkspur.example never aligns with contoso.com. The only mechanism that produces an aligned pass here is DKIM signed as the From domain — which is precisely the record the platform is asking you to publish.
An enforcing DMARC policy makes new senders fail loudly
On a domain at p=none, an unsigned new sender still reaches the inbox — the problem hides. At p=quarantine or p=reject, every unauthenticated stream is visibly junked or bounced the moment it starts. That's the policy working as designed, but it means onboarding a new sending platform is a DNS task, not a "just start sending" task. Publish the sender's DKIM first, then turn on the campaigns.
04The fix: three records, and a collision check first
One verification token, two DKIM selectors — all additive.
The platform's domain-authentication page hands you the records to publish: a TXT verification token (it proves you control the domain, so the platform will activate signing) and two CNAME selectors that point at the platform's public keys. Genericized, they look like this:
| TXT | @ → larkspur-verify-XXXXXXX — ownership token, activates signing on the platform side. |
| CNAME | larkspur.k1._domainkey → k1.dkim.larkspur.example — DKIM key 1. |
| CNAME | larkspur.k2._domainkey → k2.dkim.larkspur.example — DKIM key 2. |
Before adding anything, check every proposed name against the live zone. All three here are new: the platform uses its own selector prefix (larkspur.k1/k2._domainkey), which is distinct from the M365 selectors (selector1/2) and the transactional ones (s1/s2). Nothing overwrites, nothing collides. Just as important: the TXT token is added as a new record at the apex — it does not replace the existing SPF TXT. Multiple apex TXT records coexist normally; the classic mistake is editing SPF when you meant to add a sibling record.
The double-suffix gotcha
Most DNS hosts append the zone automatically. Enter the selector host-only — larkspur.k1._domainkey — not the fully-qualified name. Type the FQDN and you get larkspur.k1._domainkey.contoso.com.contoso.com, which resolves to nothing and fails verification with no obvious cause. When a freshly-added CNAME "just won't verify," a doubled zone suffix is the first thing to check.
Save the three records, then return to the platform's page and click Verify. Verification reads the records back; platforms typically re-check for up to 24 hours, so a "not verified yet" immediately after saving is expected, not a failure. Once it flips to verified, the platform starts DKIM-signing outbound mail as the domain, DMARC gets its aligned pass, and campaigns land in the inbox. The change is forward-looking — it doesn't rescue mail already sitting in someone's junk folder.
05What did — and didn't — change
A third authenticated sender, and nothing else touched.
The whole change is additive. M365 mail keeps signing with selector1/2; the transactional service keeps signing with s1/s2; SPF, DMARC and MX are untouched. You've added a third authenticated sender alongside the two that already worked — not modified either of them. That also makes rollback trivial: delete the three records and the zone is byte-for-byte back to where it started. Low-risk changes still deserve the discipline, though — this is production DNS on a domain the client owns, so it goes out with written approval and a confirmation that the client actually owns the sending account before anything is published.
The one-line model
"My domain is authenticated" is the wrong unit. Authentication is per sending service — every new platform that sends as your domain needs its own DKIM key published, or an enforcing DMARC policy will quietly junk everything it sends.
Further reading
- RFC 6376 — DomainKeys Identified Mail (DKIM)selectors, keys, and signing
- RFC 7489 — DMARCalignment and the pass/fail logic
- RFC 7208 — Sender Policy Framework (SPF)why the return-path domain is what SPF checks
- dmarc.org — Overviewhow SPF, DKIM and DMARC fit together
Comments
Questions or corrections welcome. Sign in with GitHub to join the thread.