Skip to content
wiki · technical reference

DKIM

A cryptographic signature on every outgoing message. Proof of authorship, proof the body wasn't altered.

~6 min read

How DKIM works mechanically

Send time. Your MTA hashes a chosen set of headers plus the message body, then signs that hash with a private RSA key. The signature gets attached to the outgoing message as a DKIM-Signature: header, with enough metadata that any receiver can do its own verification. The matching public key lives in DNS as a TXT record under whatever selector you picked.

Receive time. The receiver pulls the public key from DNS. It recomputes the hash on what it just received and checks whether the signature still matches. Match means the message wasn't altered after signing and was signed by someone who actually had the private key. No match means something is wrong, and the receiver gets to decide how much that bothers it.

The DKIM-Signature header, decoded

A typical DKIM signature on the wire:

DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=mail2026q2;
  c=relaxed/relaxed;
  h=from:to:subject:date:message-id;
  bh=zZSqKvyPg+R6PI8h7VPPkFvGfMc/...;
  b=BqRfuDUEPkcrR8oS3X9LvE3oK4ZZkVvPO...

What each tag means:

  • v=1. The DKIM version. Always 1 in current use.
  • a=rsa-sha256. Signature algorithm. RSA with SHA-256 is the modern default. Older deployments still ship rsa-sha1, which receivers either downgrade or drop.
  • d=example.com. The signing domain. This is whose reputation rides on the signature.
  • s=mail2026q2. The selector. Multiple selectors can coexist under one domain, which is how rotation works without breakage.
  • c=relaxed/relaxed. Canonicalisation. Tells the receiver how to normalise whitespace before verifying. "Relaxed" tolerates whitespace changes; "simple" doesn't.
  • h=from:to:subject:date:message-id. The headers that were signed. Receivers verify only these. Any header not listed here can be modified without breaking the signature, which matters for forwarders.
  • bh=.... Body hash, base64-encoded.
  • b=.... The actual signature, base64.

The DNS record

The matching public key is published as a TXT record at <selector>._domainkey.<domain>. For the signature above, that's mail2026q2._domainkey.example.com. The record looks like:

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
2QBs9q...lots more base64...IDAQAB

The p= tag holds the base64 public key. Need to revoke a selector? Republish the same record with p= empty. In practice nobody does this. You rotate to a new selector, let the old one expire from the wire after the overlap window, and move on.

Key length: 2048-bit or you are wasting your time

1024-bit was the standard up until around 2017. Not anymore. Gmail flags 1024-bit DKIM as weak and quietly downgrades whatever you're sending. Microsoft treats it as "authenticated, but we don't fully trust this." So if you're still on 1024-bit in 2026, you're shipping mail that already starts a lap behind.

One operational catch with 2048-bit: the resulting key exceeds the 255-byte single-string TXT limit. The standard workaround is publishing the record as multiple quoted strings that the DNS server concatenates. Most modern DNS providers handle this without you noticing. Older setups sometimes need manual splitting at the 255-byte boundary, and getting the split wrong silently breaks DKIM until someone notices the mail is failing.

To audit DKIM key length, selector hygiene, and rotation status across your domains: use our free DKIM Key Audit tool. No signup, no logs.

Selector rotation

Selectors are how you do lifecycle management without breaking sending. You don't rotate a key in place. You publish a new selector with a fresh key, switch your MTA to sign with the new selector, leave the old selector live in DNS for a while, then remove it.

Sensible policy:

  • Quarterly rotation. New selector named with the year and quarter, like 2026q1, 2026q2. Predictable, easy to audit.
  • 14-day overlap. Both DNS records live during the cutover. The MTA signs only with the new one. After two weeks any in-flight messages signed with the old key have settled, and the old selector can be pulled from DNS.
  • Immediate rotation if a key leaks. Same workflow but compressed. Hours instead of weeks. Don't wait for a quarterly window; the leak window is what matters.

Alignment with SPF and DMARC

DKIM by itself proves "someone with this private key signed this message." It doesn't prove the From: header matches the signing domain. That's where alignment comes in. DMARC requires the DKIM signing domain (the d= tag) to align with the From: header domain. Two modes:

  • Strict (s). The DKIM signing domain must exactly match the From: domain. d=example.com aligns strictly with From: foo@example.com but fails strict alignment with From: foo@mail.example.com.
  • Relaxed (r). The DKIM signing domain just needs to share an organisational domain with From:. d=mail.example.com is fine for From: foo@example.com.

DMARC defaults to relaxed, and that's what most senders should leave it on. Strict alignment is for banks, identity providers, anyone who treats subdomain mismatches as suspicious by default.

How DKIM affects deliverability

DKIM is one of three authentication signals receivers care about. The other two are SPF and DMARC, and none of the three guarantees inbox placement. Content quality matters. So does IP reputation, complaint rate, how often recipients open what you send, whether your list looks bought. Without DKIM you're missing one of three primitives every credible sender publishes. Receivers notice.

What good DKIM looks like in practice: invisible. Nobody comments on it. Mail just goes through. Bad DKIM is the opposite: Gmail routes more aggressively to spam, Microsoft SCL scoring climbs, corporate filters reject outright at the SMTP level. The 2026 baseline isn't negotiable: present, valid, aligned, 2048-bit, sha-256, rotated quarterly.

DKIM in 2026 enforcement: how Gmail and Microsoft actually use it

Through 2024-2026 the receiver-side weighting on DKIM has shifted in specific ways that operators benefit from understanding. The general pattern is that DKIM has moved from a strong-positive signal that helped placement to a binary requirement whose absence produces rejection while presence produces no special bonus.

Gmail moved to SMTP-level rejection in November 2025 for bulk senders without proper DKIM signing. The rejection codes are 550-5.7.26 for missing authentication or 421-4.7.32 for DMARC alignment failures. The bulk-sender threshold is 5,000 daily messages to personal Gmail accounts. Below that threshold the enforcement is softer but the placement penalty for unsigned mail still applies; signing has become operationally mandatory regardless of volume.

Microsoft completed equivalent enforcement on April 30, 2026 with 550 5.7.515 rejections on non-compliant bulk mail to consumer Outlook properties. The Microsoft enforcement differs slightly from Gmail in that the 5,000 daily threshold applies more strictly and the enforcement window is shorter for borderline cases. Both receivers treat unsigned bulk mail as effectively undeliverable to consumer mailboxes.

The structural implication for operators: DKIM signing is no longer optional or merely beneficial. It is required for any sending operation that reaches consumer Gmail or Outlook with non-trivial volume. The implementation cost is modest (one DKIM keypair, one DNS record, MTA configuration) but the operational consequence of skipping it has moved from reduced placement to no placement at all under 2026 conditions.

For DMARC alignment specifically, DKIM provides the alignment path that survives email forwarding while SPF does not. Senders whose recipients use email forwarding (corporate mail with personal forwarding, mailing lists, .forward files) need DKIM alignment because SPF breaks during forwarding while DKIM signatures survive intact. This makes DKIM more important than SPF for senders with audiences that include forwarding paths.

DKIM key generation and DNS publication

The mechanical procedure for adding DKIM signing to a sending domain has not changed substantially in years but operators new to it benefit from a concrete walkthrough. The steps below cover the standard procedure that produces a working DKIM setup.

Step 1: generate the keypair. Use 2048-bit RSA at minimum; receivers downgrade 1024-bit keys as documented elsewhere. The opendkim-genkey utility produces both the private key file for the MTA and the public key in the format expected for DNS publication. Alternative tools (openssl directly, the DKIMkeygen utility, custom scripts) work equivalently as long as they produce 2048-bit RSA output.

Step 2: publish the public key in DNS. The record name follows the pattern SELECTOR._domainkey.SENDING-DOMAIN where SELECTOR is an arbitrary string (operator-chosen; conventions like k2026q3 or default are common) and SENDING-DOMAIN is the domain being signed for. The record type is TXT. The content includes the public key plus optional flags. Most operators use the format v=DKIM1; k=rsa; p=PUBLIC-KEY-BASE64 with the public key as a single base64 string; some DNS providers require splitting the string across multiple TXT chunks because of the 255-character TXT segment limit, which most modern DNS providers handle automatically.

Step 3: configure the MTA to sign outbound mail. The configuration varies by MTA: PowerMTA uses VirtualMTA-specific signing configuration in the smtp-source declaration, Postfix uses opendkim or rspamd as a milter, Exim uses built-in DKIM directives in the configuration. The configuration specifies the private key file, the selector that matches the DNS record, and the signing domain.

Step 4: verify signing actually works. Send a test message to a deliverability-test service or to your own mailbox at major receivers, examine the message headers, confirm the DKIM-Signature header is present, confirm verification passes when the receiver evaluates the signature. The companion DKIM Key Audit tool on this site checks the DNS-side configuration; receiver-side verification confirms the MTA-side signing also works.

Step 5: maintain rotation discipline. As covered in the rotation section elsewhere, DKIM keys should rotate at minimum annually and ideally quarterly for high-volume senders. The rotation procedure follows: generate new keypair, publish new selector, configure MTA to sign with new selector, retain old selector for 7-14 days during transition, remove old selector after transition completes.

Multi-domain and multi-tenant DKIM configurations

Production sending operations often involve multiple domains, multiple sending pools per domain, and sometimes multiple customers (in ESP contexts) with their own domain configurations. The DKIM architecture needs to support this without becoming operationally unmanageable.

For multi-domain operations: each sending domain needs its own DKIM keypair and its own DNS record. The selectors do not need to match across domains; using consistent selectors (e.g., all domains use k2026q3 for the current quarter) simplifies operational tracking, while domain-specific selectors (e.g., customer-acme-q3) make per-domain provenance more visible in headers. Most operators choose the consistent-selector pattern because it simplifies rotation operations.

For multi-pool within a single domain: each subdomain in the sending pool needs its own DKIM keypair, published at SELECTOR._domainkey.SUBDOMAIN.PARENT. The subdomain DKIM configuration is independent of the parent domain DKIM configuration; subdomains can rotate independently and have different selector conventions if operationally convenient. The subdomain rotation entry in our wiki covers the broader architectural pattern that makes this work.

For multi-tenant ESP contexts: each customer typically signs with their own DKIM keypair on their own sending domain, while the ESP infrastructure may additionally apply its own DKIM signature on the envelope-sender domain. The dual-signature pattern is well-supported by major receivers (multiple DKIM signatures on a single message are valid and each can be evaluated independently) and provides reputation isolation between customers plus accountability at the ESP infrastructure level.

For sender-rewrite scenarios where mail flows through forwarding services: the original DKIM signature should remain intact while any infrastructure that modifies the message body needs to either preserve the signed sections (avoid touching them) or sign the modified message with its own DKIM keypair on its own domain. Common patterns where this matters include corporate mail filters that add disclaimers, mailing list software that adds list-specific footers, and CRM platforms that inject tracking pixels. The implementations that handle this correctly preserve the original DKIM and add their own; implementations that handle it poorly break the original signature without adding their own, which produces alignment failures at the receiver.

DKIM troubleshooting in 2026: common production issues

Most DKIM configurations either work or fail at initial deployment. Issues that surface later in production are typically caused by specific environmental factors that the initial deployment did not exercise. The patterns below capture the most common production-time DKIM issues.

Issue 1: signatures intermittently fail verification despite consistent configuration. Common cause is body modification by intermediate infrastructure. A milter, mailing list, or forwarding service is touching the message body after DKIM signing but before the receiver verification. The fix requires identifying which infrastructure is modifying the body and either configuring it to not modify signed content or moving DKIM signing to occur after the modification (typically at the egress MTA rather than at the application layer).

Issue 2: signatures fail at specific receivers but pass at others. Common cause is canonicalization mismatch. The DKIM specification allows multiple canonicalization algorithms (simple, relaxed); some receivers handle them differently when the message includes specific patterns (extra whitespace, certain character encodings). The fix is using relaxed canonicalization for both header and body (c=relaxed/relaxed), which most modern signing infrastructure does by default.

Issue 3: signature verification works at the receiver but DMARC still fails alignment. The signing domain in the DKIM signature does not match (or align with) the From header domain. DMARC requires either SPF or DKIM alignment to pass; if SPF is misconfigured and DKIM signs with a different domain than the From header, alignment fails despite valid signatures. The fix is ensuring the DKIM signing domain matches the From header domain or is a parent domain of it (alignment is satisfied at the organizational domain level, so signing for example.com aligns From: marketing@example.com correctly).

Issue 4: rotation produces temporary signature failures. The new selector was published in DNS but not yet propagated globally when MTAs began signing with it. Receivers query DNS for the public key and get NXDOMAIN, producing verification failure. The fix is publishing the new selector at least 24 hours before switching signing to use it, allowing global DNS propagation to complete. We typically run new selector publication 7 days ahead of MTA cutover to give substantial buffer.

Issue 5: high-volume sending produces signature processing CPU load. DKIM signing is computationally non-trivial at scale; signing 1M messages per hour produces meaningful CPU load on the MTA. The fix at high volume is signing infrastructure with adequate CPU allocation and signing hardware acceleration where available; modern PowerMTA on appropriate hardware handles signing for typical bulk operations without performance issues, but undersized infrastructure can produce queue backlogs that look like delivery problems while actually being signing performance problems.

Troubleshooting

dkim=fail (signature did not verify)
Body or signed headers got modified after the signature was applied. Mailing-list software prepending a list-tag to the subject is the classic cause. Read the Authentication-Results: header on a received message; "body hash mismatch" means content changed; "signature did not verify" means a header changed.
dkim=fail (key syntax error)
The DNS record is malformed. Common culprits: accidental line breaks, missing quotes, BIND-specific encoding glitches. Run dig TXT selector._domainkey.example.com and look at exactly what receivers see. If the output looks broken, fix the record at the DNS provider, not in your MTA config.
dkim=permerror
Either the public key DNS record doesn't exist, or the algorithm in the signature isn't supported. Verify the selector record is published. Check the algorithm; rsa-sha256 is what receivers expect; rsa-sha1 produces permerror at strict receivers.
dkim=temperror
DNS resolution failed during verification. Almost always transient. Receivers retry. If it persists, check your authoritative nameservers for outages or rate-limiting from the receiver's resolver.
dkim=neutral
Different from a failure. The message wasn't signed at all. Check that your MTA is actually configured to sign outbound mail and that the signing key is loaded. Common cause: secondary MTA or a transactional system bypassing the main signing pipeline.
My DKIM signing is using SHA-1 hashes. Should I rotate to SHA-256?
Yes, immediately. SHA-1 has been deprecated for DKIM since 2018 and most modern receivers downgrade or reject SHA-1 signatures in 2026. The DKIM Key Audit tool on this site detects SHA-1 usage. The fix is generating a new keypair using SHA-256 (the default for any modern DKIM tooling), publishing under a new selector, configuring the MTA to use the new selector. Standard rotation procedure applies. Most production sending operations that still have SHA-1 in 2026 are running legacy configurations that were set up before 2018 and never updated.
My third-party email vendor signs with their domain, not mine. Is this a problem?
Depends on what else is configured. If the vendor signing domain aligns with your From header domain at the organizational level (the vendor uses your domain in their signing identity, not theirs), this is fine and DMARC alignment works. If the vendor signs with their own domain (e.g., signing mail from From: you@example.com with d=vendor.com), DMARC alignment via DKIM fails. The vendor should support custom-domain DKIM where they sign with a subdomain of your domain (e.g., d=mail.example.com) and you publish the corresponding DNS record. Most reputable vendors support this. Vendors that do not are operating below the deliverability standard required for 2026 enforcement.

Related entries