Why does DKIM fail even when the record exists?
When the record exists, DKIM on a cold email domain usually fails for one of four reasons, and the record rules out none of them. The receiver may look up a different selector than the one you published. The record may be broken, cut short or the wrong type. Something may change the message after it was signed. Or the message may be signed with a domain that is not the one in your From address.
Three results are often confused in the email headers, and each one points somewhere different.
dkim=none means the message carried no DKIM signature at all. Usually nobody switched on signing for that domain in the sending tool or the mailbox provider.
dkim=fail means a signature was there and did not check out. The key did not match, the record was broken, or the message changed after signing. A key missing at the selector can land here too, though receivers label that case differently.
dkim=pass with DMARC failing means the signature is valid but belongs to another domain, usually the sending tool's. This one fools people, because the word "pass" is right there.
In cold email terms, DKIM (DomainKeys Identified Mail) works like this. Your tool or mailbox provider signs each email with a private key. The matching public key sits in the DNS of the sending domain, under a label called a selector. The receiving server reads the signature, asks that domain for the key and checks that the signed parts of the message did not change, as the standard RFC 6376 describes.
The same standard says a failed signature does not by itself force a rejection. Gmail is stricter: it has dedicated error codes for mail that did not pass DKIM, and code 5.7.30 means the message was blocked.
I have SPF, DKIM and DMARC live on a domain before it sends at any volume. DKIM is one record inside the boring part of cold email setup, and this article stays on that one record.
What DKIM key length should a cold sender use?
Use a 2048-bit RSA key wherever your DNS provider accepts it. Treat 1024 bits as the floor.
RFC 8301 sets 1024 bits as the minimum RSA key size for signers and 2048 as the recommendation; signers must sign with rsa-sha256, and must never use rsa-sha1. Verifiers must not accept signatures made with RSA keys under 1024 bits. Gmail's sender guidelines set 1024 bits as the minimum key for mail to personal Gmail accounts and recommend 2048.
| Option | What the standard says | Practical call for a cold domain |
|---|---|---|
| RSA under 1024 bits | Not valid for verifiers | Replace today |
| RSA 1024 bits | Allowed minimum | Only if the DNS panel truly cannot hold a longer key |
| RSA 2048 bits | Recommended | The default for every new cold domain |
| Ed25519-SHA256 | Added as a stronger algorithm; verifiers must implement it | Only as a second signature next to RSA, on its own selector |
| rsa-sha1 (any length) | Must not be used | Never |
Ed25519 comes from RFC 8463. It can sit next to an RSA signature during a transition, but each key needs its own selector, because a selector holds only one key record. For a cold sender today, a 2048-bit RSA key on its own is enough.
The real risk with 2048 bits is the DNS panel, not the math. A 2048-bit public key is a long string. Some registrar panels cut it short or break the quote marks when you paste it, and a truncated key fails every single signature. Gmail's own guidelines recommend 2048 only if your domain provider supports it. After publishing, look the record up and compare the last characters of the p= value with what your tool generated.
How do selectors and signing domains work in cold email?
Take a cold domain, tryacme.example, with a mailbox anna@tryacme.example. The sending tool gives you a selector called s1 and a public key. You publish that key at this DNS name:
s1._domainkey.tryacme.example
Every email Anna sends then carries a DKIM-Signature header with d=tryacme.example and s=s1. The receiver joins those two values into the same name and asks DNS for the key. If the header says s=mail and you published s1, the receiver asks for a record that does not exist. That is the classic "the record is there and DKIM still fails" case.
The d= value is the signing domain, and it matters more than the selector. A sending tool can sign with its own domain, so the header says d=sendingtool.example while your From line says tryacme.example. DKIM passes for the tool. DMARC then compares the signing domain with the From domain, finds two different names, and fails.
Both big mailbox providers say this plainly. Gmail requires the From domain to align with the SPF or DKIM domain for anyone sending more than 5,000 messages a day, and tells you to check that your email service provider authenticates your own domain. Microsoft's DKIM documentation says DKIM only helps a message pass DMARC when the signing domain matches the From domain, that Microsoft 365 does no DKIM signing for custom domains until you configure it, and that custom domains use two CNAME records. If you want the wider picture, here is what Gmail, Yahoo and Microsoft require from senders.
A tool's own signature next to yours does no harm, since a message can carry several signatures.
How often do cold senders need to rotate DKIM keys?
On a cold domain, triggers matter more than a calendar. Rotate immediately when:
- A private key may have been exposed, for example someone who could export it has left
- You move the domain to a different sending tool
- You move the mailboxes to a different provider
- The domain still signs with a 1024-bit key and your DNS can now hold 2048
On a domain you keep for more than a year with none of those events, rotate on a fixed date you record in your domain register, using the overlap order below.
The safe order never touches the live key first. Put a new key on a new selector: one selector holds one key, and overwriting it fails mail still in transit that was signed with the old key. Publish the new selector, confirm it resolves, switch the tool to sign with it, then keep the old record published until test sends pass on the new one. Delete the old record last. On Microsoft 365, keep both CNAME records in place at all times, because Microsoft's documentation says rotation depends on both.
What breaks rotation on cold domains is timing. Do not rotate during warm-up or in the week a campaign launches, because a failure then looks like a reputation problem and sends you chasing the wrong fix.
What makes dkim=none or dkim=fail show up?
| Symptom | Most likely cause | Fix |
|---|---|---|
| dkim=none, no DKIM-Signature header | Signing never switched on for this domain in the tool or mailbox provider | Turn on custom-domain signing, then retest |
| "no key for signature" next to the dkim= result (the label varies by receiver) | Selector in the header differs from the one in DNS, or the host field doubled the domain (s1._domainkey.tryacme.example.tryacme.example) | Publish the key at the exact name built from s= and d= |
| Microsoft 365 DKIM status stays CnameMissing and signing will not switch on | TXT record published where Microsoft expects a CNAME | Replace it with the two CNAME records Microsoft gives you, then enable signing |
| dkim=fail, signature did not verify | Key truncated by the DNS panel, or the tool signs with a new key while DNS holds the old one | Republish the full key; match the selector to the active key |
| dkim=fail, body hash did not verify | Message changed after signing: a footer, a disclaimer or a gateway | Remove the change, or move it before the signing step |
| Fails right after setup, passes later | Record not live yet; Google's Workspace DKIM setup guide says DKIM can take up to 48 hours to start working | Wait before judging the fix |
| dkim=pass, DMARC fails | Signature made with the tool's domain, not yours | Set up signing with your own cold domain |
Only one of those rows points outside your DNS and your tool: the body hash row. Every other row is fixed in DNS or in the tool's settings. A body hash failure means something is touching your mail after it leaves the tool, and the same Google setup guide warns that outbound gateways which add footers can break DKIM.
What is the fastest way to fix a "DKIM signature not valid" error?
Start from the sending domain. "Our emails go to spam" covers many domains and many causes. One domain and one mailbox can be tested quickly.
- Pick one failing domain and one mailbox on it. Send a plain test to a Gmail address and an Outlook address you control.
- Open the raw headers in both and find the Authentication-Results line. Note the dkim= result, the header.d value and the header.s value.
- Compare header.d with the domain in the From line. If header.d is neither that domain nor a subdomain of it, stop here: you have an alignment problem, and no DNS edit on the selector will fix it.
- Build the DNS name from s= and d= and look it up. Confirm the record exists, is the type your provider expects and holds the full key.
- Compare that public key with the one the tool shows for the active selector.
- If the key matches and you see a body hash error, list everything that touches the message after the tool: gateways, disclaimers, footers.
- Change one thing, wait for DNS to update, and send the same two tests again.
Two fixes in one round make the next failure impossible to read.
How should a cold email team roll DKIM out across many domains?
Cold email at a real scale is never one domain. For each cold program we run, my team buys 20 to 40 email accounts spread over 10 to 20 domains, and more for a bigger company. Each of those domains is checked separately by every receiver, so each one needs its own working DKIM.
Between 17 April and 17 May 2023, my team ran cold email next to LinkedIn for a UK company selling software development and IT consulting. The cold email side produced 41 positive replies, which turned into 13 calls and 2 sales. Every one of those 13 calls started with an email that first had to get past the receiver's authentication checks.
A cold program that runs for many months outlives its first setup: tools update, mailboxes move and somebody edits DNS without knowing what a selector is. A check done once at setup does not cover it.
The rule set for many domains:
- One domain, one key pair, one selector record. A record on one domain does nothing for another, because the receiver only queries the domain in d=.
- Every domain signs as itself, so d= always equals the From domain.
- Keep a register with the domain, mailbox provider, selector, record type, key length, date published and last test result.
- Test DKIM before warm-up starts. Warming up a domain that fails authentication burns two weeks for nothing.
- Retest any domain after a change at the registrar, the tool or the mailbox provider.
Dedicated IPs do not remove this work. My team puts every client on dedicated IP addresses, separate even across domains, and one client can run on 10 to 20 of them. That separates reputation by IP, but DKIM is checked against the domain, so a clean IP cannot rescue a broken key.
What should you check before sending volume again?
Use this as a go or no-go list, either before launch or after a DKIM fix. Every item is a yes or a no.
- Test sends to Gmail and Outlook both show dkim=pass with header.d equal to the From domain
- SPF and DMARC are published and pass on the same test sends
- The key is RSA 2048 bits, or 1024 only where the DNS panel cannot hold more
- The DNS record has stayed live and unchanged for at least a day of tests
- Nothing between the tool and the internet adds footers or rewrites the body
- New mailboxes have finished their full warm-up
My team gives every new mailbox 10 to 14 days of warm-up at minimum before it joins a campaign. Do not raise volume on a domain fresh from a DKIM fix until the checks above pass. For everything around authentication, run the 30 point outbound audit before the next launch.
If any line above is a no, that domain stays paused while the others keep sending.
If DKIM keeps failing on your cold domains and you cannot see why, book a call and we can read the headers together.
Questions about DKIM on cold email domains
Does a DKIM record in DNS mean DKIM is working?
No. The record can exist and DKIM can still fail. The receiver may look up a different selector than the one you published, the record may be broken, cut short or the wrong type, something may change the message after it was signed, or the message may be signed with a domain that is not the one in your From address.
What DKIM key length should a cold sender use?
Use a 2048-bit RSA key wherever your DNS provider accepts it, and treat 1024 bits as the floor. The risk with 2048 bits is the DNS panel: some registrar panels cut the long key short, and a truncated key fails every signature, so look the record up after publishing.
How long does DKIM take to start working after setup?
A fresh record can fail for a while before it is live. Google's Workspace DKIM setup guide says DKIM can take up to 48 hours to start working, so wait before judging the fix.
Does every cold email domain need its own DKIM setup?
Yes. One domain, one key pair, one selector record. A record on one domain does nothing for another, because the receiver only queries the domain in d=, and every domain should sign as itself.
