DKIM (DomainKeys Identified Mail) uses public-key cryptography to attach a verifiable digital signature to every outgoing email. The process involves two servers that never communicate directly: your sending mail server, which signs the message, and the receiving mail server, which fetches your public key from DNS and verifies that signature. Understanding this flow makes it much easier to configure DKIM correctly and diagnose failures.
The DKIM Signing and Verification Flow
DKIM authentication involves two distinct phases: signing (performed by the sending server) and verification (performed by the receiving server). Here is the complete sequence:
Phase 1: Signing the Outgoing Message
- Your mail server composes the outgoing message. Before delivery, the DKIM signing module takes over.
- The message is canonicalised. Canonicalisation normalises whitespace and line endings in the headers and body so that minor formatting differences between mail servers do not invalidate the signature. DKIM supports two canonicalisation algorithms:
simple(strict, minimal normalisation) andrelaxed(more tolerant of minor changes). Most deployments userelaxed/relaxed. - A hash of the message body is computed. The canonicalised body is hashed with SHA-256, producing the body hash (
bh=value). - Key headers are hashed and signed. The selected headers (From, To, Subject, Date, Message-ID, and others you choose) plus the
DKIM-Signatureheader itself are hashed and then signed using the RSA or Ed25519 private key. This produces the signature (b=). - The
DKIM-Signatureheader is added to the message before it is transmitted to the next hop.
Phase 2: Verification by the Receiving Server
- The receiving server reads the
DKIM-Signatureheader and extracts the domain (d=) and selector (s=). - A DNS TXT lookup is performed at
selector._domainkey.domain.comto retrieve the public key. - The body hash is recomputed from the received message body and compared to the
bh=value in the signature. If they differ, the body was modified and verification fails. - The header signature is verified using the public key retrieved from DNS. If the signature is valid, DKIM passes.
- The result (pass or fail) is written into the
Authentication-Resultsheader and passed to the receiving server's spam and DMARC processing engines.
The DKIM-Signature Header in Detail
Every signed message carries a DKIM-Signature header. Here is a real example, with the key fields explained:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=selector;
h=from:to:subject:date:message-id;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=abc123...base64signature...| Field | Meaning |
|---|---|
v=1 | DKIM version. Always 1. |
a=rsa-sha256 | Signing algorithm. RSA with SHA-256 is standard; Ed25519 is also valid. |
c=relaxed/relaxed | Canonicalisation algorithm for headers/body. Relaxed/relaxed is most common. |
d= | The signing domain. Must align with the From header for DMARC to pass. |
s= | The selector. Determines which DNS record holds the public key. |
h= | Headers included in the signature. From must always be included. |
bh= | Base64 SHA-256 hash of the canonicalised message body. |
b= | Base64-encoded cryptographic signature over the listed headers and the DKIM-Signature header itself. |
Where the Private Key Lives
The DKIM private key must be stored securely on — or accessible to — your outbound mail server or the email service provider (ESP) sending on your behalf. When you use a managed sending service like Google Workspace, Mailgun, or SendGrid, the provider generates a key pair and asks you to publish the public key in DNS. They retain the private key on their infrastructure.
If you operate your own mail server (Postfix, Exim, etc.), the private key is stored as a PEM file on the server, and the DKIM signing daemon (such as OpenDKIM or DKIMProxy) signs each outgoing message automatically.
How DNS Publishes the Public Key
The public key is published as a DNS TXT record at:
selector._domainkey TXT "v=DKIM1; k=rsa; p=MIGfMA0GCS..."The p= field contains the Base64-encoded public key. When you rotate keys, publish the new public key record before switching the private key on your server. This ensures receiving servers can always look up the correct key for any in-flight messages.
Common DKIM Failure Reasons
DKIM verification fails more often than it should, usually for one of these reasons:
Message Body Was Modified in Transit
Any content modification after signing — an added footer by a mailing list manager, a rewritten URL by a security gateway, or whitespace normalisation by a relay — changes the body hash. The receiving server recomputes the body hash from the modified message and finds it does not match the bh= value in the signature. Failure.
Signed Headers Were Altered
If a relay or gateway rewrites a header that was included in h= (such as Subject or From), the header hash will not match the signed value. Failure.
DNS Record Not Found or Misconfigured
If the public key TXT record at selector._domainkey.domain.com does not exist, was deleted during a migration, or contains a typo, the receiving server cannot retrieve the key and verification fails. Use the TXT Lookup tool to confirm the record is published correctly.
Key Algorithm Mismatch
If your signing server uses Ed25519 but the DNS record specifies k=rsa, or if the key sizes do not match, verification fails. The k= tag in the DNS record must match the a= field in the DKIM-Signature header.
Revoked Key (p= Is Empty)
Publishing a DKIM record with an empty p= field (p=) signals that the key has been revoked. Any message signed with the corresponding private key will immediately fail DKIM verification. This is the correct way to revoke a compromised key.
From in your signed headers — it is required by RFC 6376. Including additional headers like Subject, To, Date, andMessage-ID strengthens the signature but also increases the chance of failure if those headers are modified. Balance coverage with resilience based on your delivery path.DKIM and DMARC Alignment
For DMARC to pass on the basis of DKIM, the signing domain (d= in the DKIM-Signature) must align with the domain in the From header. In relaxed alignment (the default), the organisational domains must match — so mail.example.com aligns with example.com. In strict alignment, both must be identical. If the DKIM signing domain does not align, DMARC will not count this DKIM pass, even if the signature itself is technically valid.
Frequently Asked Questions
Why does DKIM fail for messages sent through a mailing list?
Mailing list software typically modifies the message subject (adding a list tag), appends a footer to the body, or changes the List-Unsubscribe header. Any of these changes invalidates the original DKIM signature. Some mailing list managers re-sign the message with their own DKIM key. DMARC handles this by accepting a DKIM pass from an aligned domain — if the list resigns with an aligned domain, DMARC can still pass.
Does DKIM verify the From address?
DKIM verifies that the signing domain (d=) authorised the message and that the signed content was not altered. By itself, it does not require the signing domain to match the From header. That alignment requirement is enforced by DMARC. An attacker could theoretically sign a phishing message with their own valid DKIM key while displaying a different From address — DMARC prevents this by requiring domain alignment.
Can a domain have multiple DKIM selectors active at once?
Yes. You can publish as many DKIM TXT records as you need, each under a different selector name. Google Workspace might use google._domainkey, your transactional service might usemg._domainkey, and your CRM might use k1._domainkey. Each service signs with its own private key and includes its selector in the DKIM-Signature header so receivers know which DNS record to look up.
What is DKIM canonicalisation and which should I use?
Canonicalisation normalises the message before hashing to reduce the chance of verification failures from trivial formatting differences. simple canonicalisation is strict — any whitespace change breaks the signature. relaxed canonicalisation tolerates common alterations like header folding and trailing whitespace. Use relaxed/relaxed (headers/body) for the best balance of security and deliverability.
How do I revoke a DKIM key if it is compromised?
To revoke a DKIM key immediately, update the DNS TXT record for that selector and setp= to an empty value. Any message signed with the old private key will instantly fail DKIM verification. Simultaneously, generate a new key pair, publish the new public key under a new selector, and update your mail server to use the new private key.