Glossary · DKIM

DKIM

A cryptographic signature on outgoing mail that lets receivers confirm the message was not altered and came from an authorised domain.

Definition

DKIM signs outgoing mail so receivers can verify it was not altered and came from an authorised domain. Rotate keys and keep the selector documented.

DKIM signs outgoing mail so receivers can verify it was not altered and came from an authorised domain. Rotate keys and keep the selector documented.

All glossary terms
A brass key inserted into a small engraved lock plate on dark wood.

The short version

  • DKIM signs an email with a private key held by the sender and publishes the matching public key in DNS under a selector, so a receiver can verify the message was not altered in transit.
  • It is authentication, not encryption and not authorisation. A valid signature says the domain signed this content; it says nothing about whether the recipient should trust the sender.
  • Canonicalisation decides what exactly gets hashed. Relaxed header and body canonicalisation survives forwarding and minor rewriting far better than simple.
  • The selector is the DNS label that lets you run several keys at once, which is the only way to rotate keys without breaking mail in flight.
  • DKIM only helps DMARC when the signing domain aligns with the visible From domain. A perfectly valid signature on a bounce domain does nothing for alignment.
  • Indian DNS is where most failures live: registrar panels that split long TXT strings badly, missing CNAME support at the underscore label, slow propagation and a selector that nobody documented.

What the signature actually covers

DKIM, DomainKeys Identified Mail, is defined in RFC 6376. It attaches a DKIM-Signature header to a message. That header carries a hash of selected header fields and of the body, encrypted with the sending domain’s private key, plus a selector that tells the receiver where to find the matching public key in DNS. The receiver recomputes the hash over the message it received, fetches the key, verifies the signature, and adds a result to the Authentication-Results header it will use for filtering.

The important word is selected. DKIM does not sign the whole message. It signs a declared list of header fields and the body. If a field is not in the list, it can be changed without invalidating the signature, which is a feature and a risk. A message can be modified to add a header that the signature never covered, and the signature still passes. That is why policy and user-interface signals matter alongside the cryptographic check.

Flow of DKIM signing at the sender and verification at the receiver using a DNS public key lookup. 1 Sign body 2 Add header 3 Publish key 4 Receiver hashes 5 Verify pass
Figure 1. Sign at the edge, publish the key, verify on arrival: the lookup is the step that most often fails.

The body hash is the part that catches content tampering. A signature survives a change to a header it does not cover, and fails if a single byte of the canonicalised body changes. Most of the failures that senders see are not tampering at all; they are canonicalisation mismatches caused by a mail system adding a footer, rewriting a line ending or re-encoding a character set somewhere between the signer and the verifier.

What DKIM is not doing for you

DKIM is not encryption. It does not hide the content, and it does not protect the message from being read in transit if transport encryption is absent. It also does not protect the message after delivery. A signature proves integrity between signing and verification, and nothing after that.

DKIM is not SPF. SPF, defined in RFC 7208, checks the envelope sender against a list of authorised IP addresses published in DNS. It operates on the SMTP conversation rather than the message content, it breaks when mail is forwarded, and it is limited to ten DNS lookups before it fails. DKIM operates on the message and survives forwarding, which is why the two are complementary rather than alternatives.

Comparison of SPF, DKIM and DMARC showing what each checks and what each cannot do. SPF and DKIM DMARC • Authorise sending IPs• Sign the message• Per-mechanism result• Survive or break on forward• Evidence, not policy • Ties result to From• Declares a policy• Sends aggregate reports• Requires alignment• Enforcement layer
Figure 2. Three protocols, three layers: IP authorisation, message integrity, and the policy that consumes both.

DKIM is not DMARC either. DMARC, in RFC 7489, is a policy that tells a receiver what to do when a message claiming your domain fails authentication and alignment. It consumes DKIM and SPF results. A sender can have a technically perfect DKIM signature that passes verification and still fail DMARC because the signing domain does not align with the From domain. Confusing the three leads teams to declare authentication finished while the actual policy is doing nothing.

A fourth thing DKIM does not do is establish that the domain is reputable. Receivers combine the signature result with domain reputation, engagement history and the content of the message. A brand-new domain with perfect alignment and no sending history will still be filtered, and a long-established domain with weak authentication will often be delivered anyway. Authentication removes one reason to reject mail; it does not create a reason to accept it. Teams that treat a DKIM pass as a delivery guarantee spend the next quarter debugging placement instead of fixing content and list quality.

Canonicalisation, and why relaxed wins in practice

Before hashing, the signer normalises the message according to a canonicalisation algorithm, and the receiver must normalise it the same way. RFC 6376 defines two: simple, which changes nothing, and relaxed, which collapses whitespace, trims trailing empty lines and normalises header field names and values. Header and body canonicalisation are declared separately, so a common configuration is relaxed for headers and relaxed for the body, written as relaxed/relaxed.

Simple canonicalisation is brittle. Any mail system that rewrites a line ending, appends a footer, converts quoted-printable or adds a trailing newline will break the body hash. Since almost every message passes through at least one system that does one of those things, simple is a reliable way to produce mysterious failures that appear only for some recipients. Relaxed is tolerant of exactly those transformations and is the pragmatic default.

Diagram of canonicalisation from raw message through header and body normalisation to a hash and signature. Raw Headers Body Encoding Line ends Header Relaxed Simple Trim Case fold Body Relaxed Simple Whitespace Trailing lines Result Body hash Signed hash Signature Header added
Figure 3. Two canonicalisation choices, one hash, one signature: the choice has to match at both ends.

The l= tag, which limits hashing to the first l bytes of the body, is worse than either. It was intended to let a mailing list add a footer without breaking the signature, and it also lets an attacker append content that the signature does not cover. Modern guidance is to avoid l= entirely. If a system needs to modify the body, it should re-sign rather than rely on a length limit.

Encoding is the usual culprit behind a canonicalisation failure that only affects some recipients. A template engine that converts quoted-printable to base64, a gateway that re-encodes UTF-8 as ISO-8859-1, or a client that rewrites a long line will change the bytes that were signed. Relaxed canonicalisation tolerates whitespace and line-ending changes but not a character set conversion, because the decoded octets differ. The diagnostic is to capture the message as it leaves the signer and as it arrives, then compare the canonicalised bodies directly. When they differ, look for the middleware in between rather than the signer.

Selectors: the small label that makes rotation possible

A selector is a name that identifies which key signed a message. The signature header contains s= with the selector, and the receiver looks up the public key at selector._domainkey.yourdomain, in a TXT record. The selector is arbitrary. It can be a date, a version number, a purpose or a random string. What matters is that it is unique per key, documented, and never reused for a different key.

The indirection exists so that a domain can have several keys live at once. You can publish a new selector, start signing with it, keep the old selector published while messages signed with it are still in flight or sitting in queues, and retire the old key only after a period longer than the longest delivery delay you expect. Without selectors, rotation would mean a window in which every message fails verification, which is why domains that skip rotation eventually have a very old key or no key at all.

Anatomy of a DKIM DNS record showing the selector label, version, key type, public key and flags. LoopNow runtime Selector s1._domainkey Version v=DKIM1 Key type k=rsa Public key p= base64
Figure 4. One TXT record, five tags; the p= value is the key and the k= value tells the receiver what it is.

Two operational habits make selectors manageable. First, name them so the purpose is obvious, such as s1, s2 or a month stamp, and keep a register that maps selector to key owner, algorithm, creation date and retirement date. Second, never delete a selector on the same day you stop signing with it. Mail can sit in a queue, a greylisting server or a recipient’s deferred folder for days, and verification happens on arrival, not on send.

Documentation is the part of selector hygiene that fails silently. The selector lives in a DNS record, a signing configuration, a mail platform and often a second platform for a second stream, and when the person who set it up leaves, the mapping is lost. Keep a register with the selector, the domain, the algorithm, the key size, the creation date, the owner and the planned retirement date. Store it next to the sending infrastructure rather than in a personal notebook, and review it at the same time as the domain inventory. A rotation that takes an afternoon instead of a week is a direct return on that record.

Which headers to sign, and the traps in the list

The h= tag lists the header fields covered by the signature. From is mandatory and must be present. In practice a good list also covers To, Subject, Date, Message-ID, MIME-Version, Content-Type and Reply-To, plus any header your platform relies on for routing. The rule of thumb is to sign every header that a receiver might use to decide what the message is or who sent it.

Oversigning is the technique of listing a header more times than it appears, which prevents an attacker from adding an instance that the signature does not cover. Listing From twice, for example, means an extra From header would change the hash and break the signature. It is cheap, and it closes a class of header injection that has been used in real phishing.

Wireframe of a DKIM signature header showing tags for domain, selector, headers and body hash. v and a c canonical d domain s selector h headers
Figure 5. The signature header itself: v, a, c, d, s, h, bh and b are the tags that matter most.

The traps are less obvious. Signing a header that a downstream system routinely modifies, such as a tracking header or a subject tag added by a marketing platform, guarantees failures for that stream. Signing nothing beyond From leaves Subject open to modification. And signing with a key whose DNS record is missing a p= value, or has an empty one, tells receivers the key has been revoked, which is a deliberate way to fail every signature for that selector.

The Date header deserves a note because it interacts with signature expiry. A message signed on a host with a clock a few minutes ahead can look expired when it arrives, and a host that is behind can produce a signature the receiver treats as not yet valid. Keep signing hosts on synchronised time and avoid long queues between signing and delivery. Queueing is common in Indian campaign sending during a festival peak, and a signature that was valid at signing can expire before the message leaves the queue.

Key size, algorithms and what the standards now require

RSA keys of 1024 bits were common a decade ago and are now considered too weak for signing. RFC 8301 updates RFC 6376 to require rsa-sha256 and to deprecate rsa-sha1, and it sets a floor on RSA key size. A 2048-bit RSA key is the normal choice today, and it produces a DNS record that is long enough to cause its own problems in registrar panels.

Ed25519 signing is defined for DKIM in RFC 8463 and produces much smaller keys and signatures. Support is not universal, which means it is usually deployed alongside RSA rather than instead of it: publish an ed25519 selector and an RSA selector, sign with both, and let the receiver verify whichever it understands. That improves cryptographic strength without creating a delivery cliff for receivers that only do RSA.

Chart comparing illustrative DNS record sizes for three DKIM key configurations. RSA 1024 216 chars RSA 2048 408 chars Ed25519 96 chars RSA plus Ed25519 510 chars
Figure 6. Illustrative record sizes: a 2048-bit RSA key is where registrar TXT limits start to bite.

Whatever the algorithm, the private key is the asset to protect. It should live in a key management service or an HSM-backed store, not in a repository or a configuration file on a web server. Access should be limited to the signing service, rotation should be possible without a code deploy, and every use should be logged. A leaked DKIM key lets an attacker sign mail that passes authentication for your domain, which is worse than not signing at all.

Storage of the private key deserves the same attention as its length. A key generated in a control panel and pasted into an environment variable tends to end up in a screenshot, a support ticket or a repository history. Generate it inside the key service, export only the public half, and give the signing service an identity that can use the key without reading it. If the platform cannot do that, rotate more often and treat the key as a short-lived secret rather than a fixture.

Rotation: a runbook, not an annual scramble

Rotation is the practice of replacing a signing key on a schedule and after any suspected compromise. A three to six month cadence is common for marketing streams; a shorter cadence is reasonable for high-value transactional mail. The cadence matters less than the procedure, because a rotation done badly causes an outage and an outage teaches a team to avoid rotation.

The sequence has five steps. Generate the new key pair and store the private half in the key store. Publish the new public key under a new selector and wait for DNS propagation, verified from more than one resolver. Switch the signer to the new selector and confirm that outgoing mail shows the new selector in its signature and passes verification. Keep the old selector published for at least the maximum delivery delay plus a margin. Then retire the old selector and archive the private key according to policy.

Timeline of a DKIM key rotation from generating a key pair to retiring the old selector. Day 0 Generate the new key pair Private key in KMS Day 0 Publish the new selector TXT record live Day 2 Verify from two resolvers No negative cache Day 3 Switch the signer Check Authentication-Results Day 10 Retire the old selector After max delay
Figure 7. Publish, verify, switch, wait, retire: the wait is what prevents a rotation from breaking queued mail.

The failure mode to design against is switching the signer before the DNS record is visible. Some resolvers cache negative answers, so a receiver that looked up the new selector a minute too early may keep failing for the duration of that negative TTL. Publishing first and switching after a verified propagation check, from a resolver that is not your own, removes the race. The second failure mode is retiring the old selector too early, which breaks mail that was signed before the switch and delivered after it.

Alignment is where DKIM meets DMARC

A DKIM signature passes when the cryptographic check succeeds. DMARC alignment asks a different question: does the d= domain in the signature match the domain in the From header, under the alignment mode the domain published. Relaxed alignment allows an organisational match, so mail from marketing.example.co.in signed by example.co.in can align. Strict alignment requires an exact match. Passing without aligning is the most common reason a sender has green DKIM results and a red DMARC result.

Third-party senders create the alignment problem. When an email platform signs with its own domain, the signature is valid and worthless for your DMARC policy, because the visible From is yours. The fix is to have the platform sign with your domain, which means publishing its selector in your DNS and giving it a key, or to use a CNAME delegation that lets the platform host the key under your zone. Both are standard, and both require a DNS change that a marketing team often cannot make alone.

Decision diagram for fixing DMARC alignment when a third party signs with its own domain. Who signs the mail? decision Your domain Aligns, check d= Vendor domain No alignment Vendor subdomain Delegate via CNAME
Figure 8. Three routes to alignment; the subdomain route trades reputation inheritance for isolation.

Subdomains are the pragmatic compromise. Sending marketing mail from a dedicated subdomain, signed by that subdomain, gives clean alignment and isolates reputation, so a bad campaign does not damage transactional mail. The trade-off is that the subdomain starts with no reputation, which is why it needs its own warm-up and its own monitoring rather than inheriting the parent’s standing automatically.

Indian DNS pitfalls that break otherwise correct setups

The signing logic is usually right and the DNS is usually wrong. The most common Indian problem is a registrar or hosting panel that splits a long TXT value into chunks incorrectly, inserting spaces or quoting each chunk separately. A 2048-bit RSA public key produces a value long enough that the panel’s character limit forces chunking, and a malformed record produces a permanent key lookup failure that looks like a signing problem.

The second is the underscore label. DKIM records live at s1._domainkey.example.in, and some older Indian registrar panels reject or silently drop labels beginning with an underscore, or refuse to create the CNAME that a delegated setup needs. The third is propagation. A change made at a registrar with a long TTL and a slow zone update can take hours, and a rotation scheduled without accounting for that window will fail on the first attempt and be diagnosed as a key problem.

Map of common Indian DNS failure points for DKIM records, from TXT chunking to wildcard capture. TXT chunking Split wrongly Underscore label Panel rejects CNAME delegate Unsupported Propagation Long TTL Trailing dot Absolute name Wildcard TXT Wrong value
Figure 9. Six DNS failure points; each one produces a signature that looks fine on the sending side.

Smaller traps are just as disruptive. A trailing dot added by a panel turns the record into an absolute name that does not resolve. A wildcard TXT record catches the lookup and returns the wrong value. DNSSEC, where enabled, can cause a signed zone with a broken delegation to return SERVFAIL for the key query, which receivers treat as a temporary error rather than a failure. And a selector documented nowhere means the next engineer cannot rotate the key without guessing.

Testing, reading failures and a worked example

Test from the outside. Send to a seed panel that covers Gmail, Outlook, Yahoo and at least two Indian providers, and read the Authentication-Results header rather than a dashboard summary. The header shows dkim=pass with the domain and selector, which confirms both the cryptographic result and which key was used. A pass with an unexpected selector usually means a rotation landed in the wrong environment.

Learn the four common failure strings. body hash did not verify means the body changed after signing, which is usually a footer injector or a re-encoding step. no key for signature means the DNS lookup failed, which is usually the selector name, the underscore label or propagation. signature expired means the timestamp is outside the receiver’s tolerance, which is usually a clock skew on the signing host. key revoked means p= is empty, which is deliberate and should never appear by accident.

Flow of diagnosing a DKIM failure from an Authentication-Results header to a DNS or body fix. 1 Read result 2 Check selector 3 Query DNS 4 Compare body 5 Fix and resend
Figure 10. Diagnose from the result string outward; the header tells you whether to look at content or at DNS.

A Jaipur retailer with about 400,000 messages a month had DKIM passing for transactional mail and failing intermittently for campaigns. The seed test showed the campaign stream adding a footer image after signing, which changed the body. The team moved the footer into the template before signing, switched to relaxed/relaxed canonicalisation, and published a second selector so the next rotation could run without a gap. Campaign DKIM pass rates went from 71% to 99.6% over a week, and the DMARC aggregate reports stopped showing a third of the volume as unauthenticated.

Keep a small, permanent record of authentication results per stream. A table with the date, the sending domain, the selector, the DKIM and SPF results, the DMARC disposition and the provider turns a vague complaint about deliverability into a trend line. When a rotation goes wrong, the table shows the exact day the selector changed, which is faster than reading logs. It also gives you evidence for a client review that does not depend on anyone remembering what happened in March.

Frequently asked questions

What does DKIM actually prove?

That the message content and the listed header fields were signed by the holder of a private key whose public half is published in DNS for that domain, and that the content has not changed since signing. It proves integrity and domain association. It does not prove the sender is honest, does not encrypt anything and does not by itself decide inbox placement.

What is a DKIM selector?

The label in the s= tag that tells a receiver which public key to fetch. The record lives at selector._domainkey.yourdomain as a TXT entry. Selectors let you keep several keys live at once, which is what makes rotation safe. Name them meaningfully, keep a register of which key each selector holds, and never reuse a selector for a different key.

Should I use simple or relaxed canonicalisation?

Relaxed for headers and body in almost every case. Simple breaks whenever any system rewrites a line ending, appends a footer or re-encodes the body, and most messages pass through at least one such system. Relaxed tolerates those changes. Avoid the l= length tag entirely, because it lets content be appended outside the signed portion.

How often should DKIM keys be rotated?

Every three to six months for most streams, and immediately after any suspected compromise. The cadence matters less than the procedure: publish the new selector, verify propagation from an external resolver, switch the signer, keep the old selector live for longer than the maximum delivery delay, then retire it. Switching before propagation is the most common cause of a rotation outage.

Why does DKIM pass but DMARC still fail?

Because DKIM alignment is separate from DKIM verification. DMARC checks whether the d= domain in a passing signature matches the From domain under relaxed or strict alignment. A third-party sender signing with its own domain produces a valid signature that does not align. Fix it by having the vendor sign with your domain or by delegating a selector via CNAME.

Does DKIM work with mailing lists and forwarders?

Often, if relaxed canonicalisation is used and the forwarder does not modify the body. A list that adds a footer or rewrites the subject will break the signature unless it re-signs. This is why DMARC relies on at least one of SPF or DKIM aligning, and why forwarded mail frequently fails SPF while DKIM survives.

Is a 1024-bit RSA key still acceptable?

No. RFC 8301 deprecates rsa-sha1 and sets a floor on RSA key size, and 2048 bits is the practical minimum today. The cost is a longer DNS record, which is exactly where Indian registrar panels start to misbehave. Ed25519 is smaller and stronger but not universally supported, so publish it alongside RSA rather than instead of it.

Why does my DKIM record fail to resolve in India?

Usually one of four things: the registrar split a long TXT value incorrectly, the panel refuses labels starting with an underscore, a CNAME delegation is unsupported, or propagation has not finished. Check from two external resolvers, confirm the exact name including the underscore, and look for a wildcard TXT record catching the query and returning the wrong value.

What does body hash did not verify mean?

The canonicalised body the receiver hashed does not match the bh= value in the signature, so something changed the message after it was signed. Common causes are a footer or disclaimer injected by a gateway, a character set re-encoding, a line ending conversion, or a template engine that rewrites content after signing. Move the change before the signing step.

Sources and further reading

  1. RFC 6376, DomainKeys Identified Mail Signatures
  2. RFC 8301, Cryptographic Algorithm and Key Usage Update to DKIM
  3. RFC 8463, Ed25519 signing for DKIM
  4. RFC 7208, Sender Policy Framework
  5. RFC 7489, Domain-based Message Authentication, Reporting and Conformance
LoopNow AI Answers from published LoopNow pages
Hi — ask me about LoopNow products, pricing, DPDP or migration. I answer from the published site and can connect you to the team.
Contact page