Support Library
DKIM Explained: Selectors and Key Rotation
DKIM lets a sending domain sign each email with a private key and publish the matching public key in DNS under a selector name, so receivers can confirm the message really came from that domain and was not altered.
The short answer
DomainKeys Identified Mail, or DKIM, is defined in RFC 6376. A sending server signs selected headers and the body of each message with a private key, and adds the result as a DKIM-Signature header. The signature names a domain (d=) and a selector (s=). A receiver combines them into a DNS name, fetches the public key from a TXT record there, and checks the signature.
Selectors are what make DKIM manageable. Because the key lives at a name such as s2026a._domainkey.example.com, a domain can publish many keys at once: one per sending service, and a new one next to the old one during rotation.
DKIM tells a receiver that a domain took responsibility for a message. It is DMARC that tells the receiver what to do when that proof is missing, and DMARC only counts DKIM when the signing domain aligns with the From address.
How a DKIM signature works
The signer first canonicalizes the message, which normalizes whitespace and header case so that harmless changes in transit do not break the signature. It hashes the body into the bh= tag, then signs that hash together with the headers listed in h=. The verifier repeats the same steps with the public key from DNS.
signs with private key
DKIM-Signature header
selector._domainkey.domain
verifies hash and signature
A typical signature header looks like this, with the long values shortened:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
s=s2026a; t=1760486400; h=from:to:subject:date:message-id:mime-version;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=Kx4Fv0c8...truncated...Qe1w==
| Tag | Meaning | Notes |
|---|---|---|
| d= | Signing domain | The domain that takes responsibility; used for DMARC alignment |
| s= | Selector | Picks which public key to fetch from DNS |
| a= | Algorithm | rsa-sha256 or ed25519-sha256 |
| c= | Canonicalization | relaxed/relaxed survives more in-transit rewriting than simple |
| h= | Signed headers | Must include From; listing a header name more times than it appears also protects against added copies |
| bh= / b= | Body hash and signature | A body hash mismatch means the body changed after signing |
| l= | Body length limit | Best avoided, because content appended after the limit stays unsigned |
Selectors and the DNS record
The public key record lives at <selector>._domainkey.<domain> as a TXT record. Its main tags are v=DKIM1, the key type k= (RSA when omitted), and the base64 public key in p=. An optional t=y flag marks the domain as testing DKIM, and an empty p= means the key has been revoked.
$ dig +short TXT s2026a._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu2v7...first 255 bytes"
"...remaining part of the key...IDAQAB"
$ dig +short CNAME s1._domainkey.example.com
s1.dkim.mail-provider.example.net.
Two details in that output trip people up. First, a single string inside a TXT record is limited to 255 bytes, and a 2048-bit RSA key is longer than that. The key is therefore split into several quoted strings inside one record, and verifiers join them back together. Splitting it into two separate TXT records instead is a common and fatal mistake. Second, many email services ask you to publish a CNAME instead of a TXT record. The selector then points at a name the service controls, which lets the service rotate its own keys without asking you to edit DNS.
Selector names are free-form. Good practice is to make them meaningful but not secret, for example by including the service and a date, such as mkt2026q4. That makes it obvious during an audit which keys are current and which are leftovers.
Key types and sizes
RFC 8301 updated DKIM's cryptographic requirements. Signers must not use rsa-sha1, RSA keys must be at least 1024 bits, and signers should use at least 2048 bits. RFC 8463 added Ed25519 keys, which are short enough to fit easily in DNS. Verifier support for Ed25519 is not universal, so domains that adopt it usually sign each message twice, once with RSA and once with Ed25519, using two selectors. A verifier that does not understand one signature ignores it and evaluates the other.
If you still have 1024-bit RSA keys in use, moving to 2048 bits is a normal rotation, described next.
Rotating DKIM keys safely
Rotation limits the damage a leaked private key can do and gives you a routine you can trust when you need to replace a key in a hurry. The rule that keeps rotation safe is simple: the new public key must be visible in DNS before the first message is signed with it, and the old public key must stay visible until no message signed with it can still be checked.
| Step | Action | Wait before next step |
|---|---|---|
| 1 | Generate a new key pair and publish the public key under a new selector | At least the TTL of any cached negative answer for that name, then confirm with dig against your authoritative servers |
| 2 | Switch the signer to the new selector and private key | Several days, so delayed, queued and retried mail has been delivered and checked |
| 3 | Revoke the old selector by publishing it with an empty p= | Optional grace period for audits |
| 4 | Delete the old record and destroy the old private key | None |
Notice that the new selector name matters in step 1. If you reuse the old selector name and overwrite its key, receivers that cached the old key will fail messages signed with the new one until the TTL runs out, and messages still in flight with the old signature will fail once the new key arrives. A fresh selector avoids both problems. Negative caching is explained further in Negative Caching and the SOA Minimum.
Many organizations rotate on a fixed schedule, such as every six or twelve months, and immediately after any suspected compromise of a mail server or sending account. Whatever the schedule, write the steps down and rehearse them before you need them.
DKIM, SPF and DMARC alignment
DKIM on its own does not stop someone spoofing your From address, because an attacker can sign mail with their own domain. DMARC closes that gap by requiring that either SPF or DKIM passes and that the passing domain aligns with the domain in the From header. With relaxed alignment, d=mail.example.com aligns with a From address at example.com because they share an organizational domain. A service that signs with d=sender.example.net does not align.
DKIM has one big advantage over SPF: it usually survives simple forwarding, because the signature travels with the message instead of depending on the connecting IP address. Mailing lists that add footers or rewrite subjects do break it. The ARC protocol in RFC 8617 lets intermediaries record what they saw before modifying a message. For the SPF and DMARC side of the picture, see SPF/DMARC Misconfigurations.
| Symptom in headers | Likely cause |
|---|---|
| dkim=fail (body hash did not verify) | A gateway, list or footer tool changed the body after signing |
| dkim=permerror (no key for signature) | Selector record missing, misspelled, or published in the wrong zone |
| dkim=fail (bad signature) | Key in DNS does not match the private key, often after an incomplete rotation |
| dkim=pass but dmarc=fail | The d= domain does not align with the From domain |
How DNS Panopticon helps
Domain Visualizer is the tool for mail records. Its scan looks up DKIM at two selectors, selector1 and selector2 (the names Microsoft 365 uses), along with SPF, DMARC, MTA-STS, TLS-RPT and BIMI. If neither selector exists it reports an informational finding only, because DKIM selectors are chosen by each sending service and a missing selector1 says nothing about the selectors you actually use. Read the s= and d= tags from a real message's DKIM-Signature header and check that selector with dig as shown above. Website Recon focuses on websites and registration and does not check mail records.
For an inventory, load a zone export into Zone Analyzer and filter hostnames on _domainkey. You get every selector you publish in one grid, which makes stale keys from retired services easy to spot and export as CSV for cleanup.
FAQ
Can I list all the DKIM selectors a domain uses?
Not from DNS alone. DNS has no standard way to list the names under _domainkey, so you find selectors in the DKIM-Signature headers of real messages, in your sending services' settings, or in your own zone file.
Should I delete an old DKIM key record or leave it empty?
Either works once no mail signed with it is still in flight. Publishing the record with an empty p= tag tells verifiers the key was revoked on purpose, which some operators prefer for a while before deleting the record.
Does a DKIM pass mean DMARC passes?
Only if the signing domain in d= aligns with the domain in the visible From header. A message signed by a sending service with its own domain can pass DKIM and still fail DMARC.