What a DKIM signature proves
DKIM, defined by RFC 6376, lets a domain take responsibility for a message in a way that a receiver can verify without contacting the sender. The signing system hashes the message body, hashes a named list of headers together with the signature header itself, signs the result with a private key, and adds the whole thing as a DKIM-Signature header.
A verifying receiver reads the d= and s= tags to work out where the public key lives, fetches it from DNS, and checks the signature. A pass means two things and only two: the domain named in d= holds the private key, and every part of the message that was signed is byte-for-byte what it was at signing time. It is not a statement that the message is wanted, and it is not by itself a statement about the address in the header From — that connection is made by DMARC.
Key pairs and selectors
DKIM uses an ordinary asymmetric key pair. The private half stays on the signing system and is never published; the public half goes into DNS. A domain may have any number of key pairs in use at once, and the selector is what tells them apart.
A DKIM selector is an arbitrary label chosen by whoever publishes the key — s2026a, mktg, or a random string a provider generated. It appears in the s= tag of the signature and forms part of the DNS name the key is published at, which is the selector, then the fixed label _domainkey, then the domain.
Give every sending platform its own selector. It costs nothing, it means a provider rotating their key cannot disturb anyone else's signing, and it makes an aggregate report immediately legible: the selector tells you which system sent the mail.
The public key record
The key record is a TXT record with its own small tag language. In practice only three tags matter: v, which is DKIM1 if present, k, which names the key type and defaults to rsa, and p, which carries the base64 public key.
Two optional tags are worth recognising. A t=y flag marks the key as being in testing, and asks receivers not to treat a failure as they otherwise would — useful during setup and a mistake to leave behind. An empty p= revokes the key: it is how you retire a selector without deleting the record, which keeps verification deterministic rather than dependent on an NXDOMAIN.
A 2048-bit key does not fit in a single 255-octet TXT string, so it is published as several quoted strings that a resolver concatenates in order. The join must not introduce whitespace into the base64.
s2026a._domainkey.example.com. 3600 IN TXT (
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy1Rm"
"9kVfQ2bTgH0pL7cXn4sJvW6oZaKdRtYuI3eB1MxN8QpCvA5rF0jS7hDgUwYbE2lO"
"... base64 continues ... IDAQAB" )
The signature header, tag by tag
The DKIM-Signature header is self-describing: everything a verifier needs, apart from the public key, is in the header itself.
- a= is the algorithm. rsa-sha256 is the common choice; ed25519-sha256 was added by RFC 8463. RFC 8301 forbids rsa-sha1 outright.
- d= is the signing domain and s= the selector, which together give the DNS name of the key.
- h= is the ordered list of signed headers. From must be signed. Signing volatile headers is how signatures get broken, so the list is usually short.
- bh= is the body hash and b= the signature itself.
- c= gives the header and body canonicalisation, as two names separated by a slash.
- l= optionally limits how much of the body is covered. Anything appended past that length verifies happily, which is a hole rather than a feature; leave it out.
- t= is the signing time and x= an optional expiry, after which verifiers may refuse the signature.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
s=s2026a; t=1785974400; h=from:to:subject:date:message-id;
bh=Zt9Hk2Qw8fVn3Lc0aXpR7yTuB6mS1dJgEo4WvKxNqPs=;
b=Lk3Qm9tAqR8xW1cV5nZ0pYf7Hs2Ke...
Canonicalisation
Mail in transit is not treated as immutable. Servers unfold headers, re-wrap long lines, adjust whitespace and add or strip trailing blank lines, none of which changes the meaning of the message but all of which changes its bytes. Canonicalisation is the agreed normalisation applied before hashing so that harmless changes do not invalidate a signature.
RFC 6376 defines two algorithms for each half. Simple header canonicalisation permits no change at all; relaxed lowercases header names, unfolds continuation lines, collapses runs of whitespace and strips trailing whitespace. Simple body canonicalisation ignores trailing empty lines only; relaxed additionally ignores whitespace at the end of lines and collapses internal runs of whitespace.
Use relaxed for both. Simple canonicalisation produces signatures that break for reasons nobody can act on, and offers no security benefit worth that.
Key length and algorithm
RFC 8301 sets a floor under DKIM key length: signers must use RSA keys of at least 1024 bits, verifiers must not accept anything shorter, and rsa-sha1 is prohibited. In practice 2048 bits is the working default — long enough to be uncontroversial, short enough that the record still publishes cleanly through DNS providers with awkward TXT handling.
Ed25519 signing, from RFC 8463, produces a key small enough to fit in one TXT string and a much shorter signature, but verifier support is not universal, so it is normally deployed as a second signature alongside RSA rather than as a replacement. Signing twice is legitimate: a message may carry several DKIM-Signature headers, and a verifier needs only one of them to validate.
Rotating a key without breaking mail
Key rotation is worth doing on a schedule, and it is safe as long as the publish and the cutover are separate steps. Messages already in flight are still verified against the key that signed them, so the old record must stay published until they have all been delivered or expired.
- Generate the new pair and publish the public half under a new selector.
- Wait for the record to propagate — at least the TTL of the zone, and longer if a provider caches aggressively.
- Switch the signing system to the new selector. Signatures now name the new key while the old record is still resolvable.
- Leave the old selector published for a grace period covering retries and delayed delivery. A few days is usually sufficient.
- Revoke the old selector by replacing its p= value with nothing, rather than deleting the record.
- Check that DMARC aggregate reports still show DKIM passing with the new selector before rotating anything else.
Why a valid signature breaks in transit
A DKIM failure on mail you genuinely sent almost never means the key is wrong. It means something between you and the recipient changed a byte that was covered by the signature.
- A mailing list appends a footer or rewrites the subject line to add a tag, changing both the body hash and a signed header.
- A gateway or security appliance rewrites URLs in the body for click protection.
- A relay re-wraps long lines or converts encodings, which relaxed canonicalisation absorbs only up to a point.
- A signed header was one the path is entitled to change, or a header listed in h= was absent at signing and added later.
- The key record was deleted, or the selector was rotated before mail signed with the old one had drained.
- The record was published with whitespace inside the base64 key, or with smart quotes substituted by a control panel.
- ARC, defined by RFC 8617, exists for the first case: an intermediary that must modify a message can seal the authentication results it observed, letting the final receiver see that the message authenticated before it was altered.
Check this on your own domain. The dkim record checker reads the live records and reports what a receiver would see.
Open the dkim record checkerCommon questions
- What is a DKIM selector for?
- A selector names one key among several for the same domain. It appears in the signature's s= tag and in the DNS name the public key is published at, alongside the fixed _domainkey label. Using a separate selector per sending platform lets each rotate its key independently, and makes it obvious from a report which system signed a given message.
- How long should a DKIM key be?
- Use 2048-bit RSA. RFC 8301 requires at least 1024 bits and forbids rsa-sha1, but 1024 is now the floor rather than a target. A 2048-bit public key exceeds the 255-octet limit of a single TXT string and must be published as several strings, which the resolver joins with nothing in between.
- Why does DKIM fail on mail sent through a mailing list?
- Lists commonly add a footer to the body and a tag to the subject line. Both are usually covered by the signature, so the hashes no longer match and verification fails even though the key and the record are correct. ARC exists to carry the original authentication result across such an intermediary.
- Can one message carry more than one DKIM signature?
- Yes. A message may carry several DKIM-Signature headers, from different domains or with different algorithms, and a verifier needs only one to validate. This is how Ed25519 is deployed alongside RSA, and how a sending platform signs with its own domain while also signing with yours.
- How do I retire an old DKIM selector safely?
- Do not delete the record. Leave it published for a grace period after the signing system has moved to the new selector, so that delayed and retried mail still verifies, then replace the p= value with an empty one. An empty public key is an explicit revocation, which is clearer to a verifier than a name that no longer resolves.
Keep reading
Related checks, definitions and guides.
- How SPF, DKIM and DMARC fit together Where a DKIM pass becomes an aligned pass.
- Publishing and tightening a DMARC policy DKIM alignment is what survives forwarding.
- Reading a message's headers Where to find the signature and the verification result.
- DKIM The one-paragraph definition.
- DKIM selector How several keys coexist on one domain.
- ARC How an intermediary preserves an authentication result it is about to break.