DKIM is a cryptographic signature added to your outgoing mail that receivers can verify against a public key published in your DNS. It's surprisingly robust, deeply tedious to rotate, and almost never the source of your deliverability problem — unless it's the entire source.
The 30-second mental model
When your mail platform (Google Workspace, M365, Mailchimp, your own SMTP server) sends a message, it computes a cryptographic hash over selected headers and the body, signs that hash with a private key, and stuffs the signature into aDKIM-Signature header. The matching public key is published in your DNS at a name like google._domainkey.acme.com.
Receivers extract the signature, fetch the public key, verify the math, and compare the signed body to what they actually received. If anything was tampered with in transit — or if the key doesn't resolve — DKIM fails.
Anatomy of a DKIM-Signature header
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=acme.com; s=google;
h=from:to:subject:date:message-id;
bh=mYpr5...; b=BcjK19+...The fields that matter to operators:
d=acme.com— signing domain. This is what receivers compare against yourFrom:for DMARC alignment.s=google— selector. Tells receivers where to find the public key:<s>._domainkey.<d>. Here, that'sgoogle._domainkey.acme.com.h=from:to:subject:date:message-id— the headers that were signed. Anything not in this list can be altered in transit without breaking DKIM. (This is why mailing lists that rewrite Subject lines often break DKIM — but only when the list signs in.)bh=...— body hash. Everything else is the signature over those headers + bh.
The public key in DNS
At google._domainkey.acme.com you publish:
google._domainkey.acme.com. IN TXT
"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB..."v=DKIM1— protocol version. Required.k=rsa— key type. RSA is universal; ed25519 is supported but not yet ubiquitous.p=...— the actual public key (base64). The key length matters: 1024-bit is the de-facto floor (M365 used to ship 1024-bit by default), but 2048 is what we recommend for new setups.
Pass vs. align — the part that bites operators
Two different concepts, frequently confused:
- DKIM pass: the signature is cryptographically valid. The body wasn't altered, the public key resolves, the math checks out.
- DKIM aligned: the
d=domain in the signature matches the domain in yourFrom:header (subject toadkimstrict/relaxed).
A message can pass DKIM and still fail DMARC alignment if the signing domain is something like d=mailchimp.com while the From: is marketing@acme.com. The signature is valid; it just doesn't prove acme.com authorised the message. DMARC rejects it.
This is why most ESPs offer a “custom DKIM” or “authenticated domain” feature: you publish a CNAME (or sometimes a key directly) in your DNS so the ESP can sign withd=acme.cominstead ofd=mailchimp.com. That's the alignment fix. Until you do it, your perfectly-valid DKIM signatures are delivering you no DMARC value.
Selectors — why there are usually several
Each ESP gets its own selector under the same domain:
google._domainkey.acme.com— Google Workspacek1._domainkey.acme.com— Mailchimpselector1._domainkey.acme.com— M365 (the other one isselector2)s1._domainkey.acme.com— SendGrid
A receiver looks at the message's DKIM-Signature header, sees s=k1; d=acme.com, and knows to fetch the key from k1._domainkey.acme.com. The selector name is arbitrary; ESPs pick whatever they want. That's why there's no universal rule for what your selectors look like.
Key rotation — the tedious part
Best practice is to rotate DKIM keys periodically (some standards bodies say quarterly; most operators do it annually or only when forced). Rotation is awkward because:
- You can't just swap the key — messages signed with the old key are still in transit and need to verify against the old public key.
- So you publish the new key under a fresh selector (e.g.
k2._domainkey.acme.com), reconfigure your ESP to sign withs=k2, wait the duration of the longest possible mail-in-flight (~7 days), then revoke the old key. - Revocation is publishing a key with empty
p=:v=DKIM1; p=(literally nothing after the equals).
For most teams, “rotate annually” means “rotate when you remember.” Mailstinger flags DKIM keys older than 365 days in the dashboard.
What makes DKIM survive forwarding
Email gets forwarded. SPF breaks immediately on forward (the new sending IP isn't in your SPF record). DKIM survives if and only if the forwarder doesn't alter the signed headers or the body.
This is why DMARC at p=quarantine or p=reject often produces the surprise ofyour own forwarded internal mail being quarantined. A user with a forward set up has their forwarded message fail SPF (no question), and if their server rewrites the Subject, DKIM also fails. With both signatures broken, DMARC enforces. The cure: configure your forwarders to preserve headers + body verbatim, or whitelist your forward domains explicitly.
2024+ enforcement context
The Google/Yahoo February 2024 rules require DKIM signing for any sender doing >5,000 messages a day to their inboxes. Microsoft signalled similar enforcement later in the year. Combined, that's ~70% of US inboxes mandating DKIM as table stakes — not optional, not aspirational, mandatory. If your bulk mail isn't DKIM-aligned, your delivery rate has already dropped and you may not have noticed.
Things people get wrong
- “I have DKIM, so DMARC will pass.” Only if it's aligned. See above.
- “I'll just sign with my domain at send time.” If you don't control the sending platform's signing flow, you can't. Use the platform's authenticated-domain feature.
- “DKIM proves the sender is legitimate.” DKIM proves the message was signed by a holder of the private key for
d=. Whetherd=should be trusted is DMARC's problem. - “I'll publish a 1024-bit key.” Old guidance, still everywhere. New guidance: 2048-bit RSA or ed25519. Some receivers (notably Google) don't check below 1024 anymore but flag mid-sized keys as weak.
How to audit yours
The fastest tell: pick a recent legitimate email from your domain, view its raw source, find the DKIM-Signature header, and check what d= says. If it's not your domain (e.g., d=mailchimp.com for a marketing send from marketing@acme.com), DKIM is signing but not aligning. That's your fix.
Or paste the headers into our header analyzer and it surfaces the auth-results verdict in plain English.