DKIM: From Theory to Production Implementation

  • April 2022
  • Engineering Memo · External Release

DKIM (DomainKeys Identified Mail) is the authentication standard that allows receiving mail servers to verify that a message was signed by the domain it claims to come from, and that the message has not been altered in transit. Understanding DKIM at the specification level — public-private key pairs, DNS TXT records, signature headers — is straightforward. Implementing DKIM correctly in a production email infrastructure, at scale, with multiple signing domains and rotating keys, is where the operational details matter and where misconfiguration produces authentication failures that are difficult to diagnose without understanding the system's internals.

This note covers the operational implementation of DKIM in PowerMTA environments: key generation, DNS publication, selector management, key rotation, algorithm selection, and the specific failure modes that production environments encounter but that introductory DKIM documentation does not address.

DKIM Architecture: Keys, Selectors, and DNS

DKIM authentication uses asymmetric cryptography: the sender signs each outgoing message with a private key stored on the sending server; the receiver verifies the signature using the corresponding public key published in DNS. The connection between a specific private key and its DNS-published public key is made through the selector — a label in the DKIM-Signature header that tells the receiving server which DNS record to check for the public key.

The DNS TXT record for a DKIM public key is published at selector._domainkey.yourdomain.com. For example, if the selector is "s1" and the signing domain is "example.com", the public key is published at s1._domainkey.example.com. The receiving server reads the s= tag from the DKIM-Signature header (which specifies the selector), constructs the DNS lookup name, retrieves the public key from DNS, and uses it to verify the signature.

Multiple selectors can be active for the same domain simultaneously — this is how key rotation works without disrupting authentication. During a key rotation, the new key is published under a new selector before it is used for signing; messages signed with the old key continue to verify against the old selector's DNS record; messages signed with the new key verify against the new selector's record. Only after the old key has been fully retired (no messages remain in transit signed with the old key) is the old selector's DNS record removed.

Figure 1 — DKIM Signing and Verification Flow

Sending MTA Private key stored Signs message body + headers Adds DKIM-Signature header DNS Public key at s1._domainkey.domain.com TXT record Receiving MTA Reads s= from DKIM-Sig Queries DNS for pubkey Verifies signature Message Message DNS lookup for public key Pass / Fail result Informs DMARC evaluation

Key Generation: RSA vs Ed25519

DKIM supports multiple cryptographic algorithms. The two in active use for production DKIM signing are RSA-SHA256 and Ed25519. RSA-SHA256 has been the standard since DKIM's adoption — it is universally supported by all receiving mail servers and all DKIM verification libraries. Ed25519 is a newer elliptic curve algorithm that produces smaller signatures and shorter public keys, reducing message size and DNS TXT record length, while providing equivalent or better cryptographic security than RSA-2048.

For production DKIM signing, the current recommendation is RSA-2048-SHA256 as the primary signing algorithm (for universal compatibility) with optional Ed25519 as a secondary signature. RFC 8463 (2018) added Ed25519 support to DKIM; major receivers including Gmail and Microsoft support Ed25519 DKIM verification. However, some receiving systems do not yet support Ed25519, which means that Ed25519-only signing can produce DKIM failures at these systems — the DKIM-Signature header is not recognised and the message is treated as unsigned.

The dual-signature approach — signing each message with both an RSA-2048 key and an Ed25519 key — provides the best of both: full compatibility via the RSA signature for all receivers, and the efficiency benefits of Ed25519 for receivers that support it. PowerMTA supports dual-algorithm signing through multiple signing-domain configurations applied to the same VMTA. The dual-signature adds approximately 400 bytes to each message — negligible for most messages, but worth considering for very high-volume programmes where cumulative bandwidth costs are significant.

PowerMTA DKIM Configuration

PowerMTA's DKIM signing is configured in the dkim-signing section of the virtual MTA configuration. The minimal configuration for a signing domain:

<dkim-signing>
  # RSA-2048 primary signature
  key           mail  rsa  /etc/pmta/dkim/example.com.s1.rsa.private
  sign          *@example.com  mail  example.com  s1  rsa-sha256  relaxed/relaxed
  
  # Ed25519 secondary signature (optional)
  key           mail-ed  ed25519  /etc/pmta/dkim/example.com.s1.ed.private
  sign          *@example.com  mail-ed  example.com  s1ed  ed25519-sha256  relaxed/relaxed
</dkim-signing>

The relaxed/relaxed canonicalization algorithm is the standard choice for production signing. It allows minor whitespace normalization in the message headers and body, which prevents signature failures from minor transformations that some mail relays apply to messages in transit. The alternative (simple/simple) is more strict — any modification to the message breaks the signature — which produces authentication failures at some ISPs that apply header folding or whitespace normalization during transit.

The signed header list (the h= tag in the DKIM-Signature) should include at minimum: From, To, Subject, Date, MIME-Version, Content-Type. Adding Message-ID to the signed header list is recommended — it links the DKIM signature to the specific message, preventing signature reuse attacks. The l= body length tag is not recommended in production: it limits the signed portion of the body to a specified number of bytes, allowing unsigned content to be appended to messages — which is a security risk rather than a usability feature.

Key Rotation Protocol

DKIM private keys should be rotated every 6–12 months as a security best practice. The rotation protocol ensures that authentication is not interrupted during the transition:

Step 1 — Generate new key pair: Generate a new RSA-2048 or Ed25519 private key. The new key must use a new selector name (e.g., if the current selector is "s1", the new selector is "s2"). Do not reuse selector names — DNS TTL caching means that a recycled selector name may serve the old public key for up to 24 hours after the DNS record is updated.

Step 2 — Publish new public key in DNS: Add the new selector's TXT record to DNS. Wait for the DNS TTL to expire (minimum 1 hour, typically 24 hours if TTL is 86400) before moving to step 3. This waiting period ensures that all receiving servers that might verify messages signed with the new key have had the opportunity to cache the new DNS record.

Step 3 — Update PowerMTA to use new key: Add the new key to PowerMTA's dkim-signing configuration with the new selector name. Reload the PowerMTA configuration. From this point, new messages are signed with the new key. Old messages already in transit (in the delivery queue) will continue to be verified against the old selector's DNS record, which is still active.

Step 4 — Retire old selector: After the queue is clear of messages signed with the old key (typically 24–72 hours after the configuration update), remove the old key from PowerMTA's dkim-signing configuration and remove the old selector's TXT record from DNS. Removing the DNS record before the queue clears would cause authentication failures for messages signed with the old key that are still in delivery retry cycles.

Table 1 — DKIM key rotation checklist

Step Action Wait before next step
1Generate new key pair with new selector (s2)None
2Publish s2 TXT record in DNSDNS TTL (min 1 hour, typically 24h)
3Update PowerMTA config to sign with s2Queue clear (24–72 hours)
4Remove s1 from PowerMTA config, then remove s1 TXT from DNSNone — rotation complete

Common DKIM Failure Modes in Production

Body hash mismatch (bh= mismatch): The body hash in the DKIM-Signature header does not match the computed hash of the received message body. The most common cause is a mail relay in the delivery path that modifies the message body after signing — adding or modifying a footer, changing line endings, or altering MIME boundaries. Investigation: check the Received headers to identify intermediate mail relays, test with a direct delivery path that bypasses the relay, and if the relay is necessary, explore whether it can be configured to not modify signed messages.

Selector not found (NXDOMAIN or no TXT record): The DNS lookup for the selector TXT record returns no results. Causes: the selector TXT record was not published, was published at the wrong DNS name, was published in the wrong DNS zone, or was removed prematurely during a key rotation. Verification: use dig TXT s1._domainkey.yourdomain.com to confirm the record exists and is correctly formatted.

Key format error: The TXT record is published but the public key within it is not correctly formatted. The DKIM TXT record format requires the key data to be split into 255-character chunks if the raw base64-encoded key exceeds 255 bytes — RSA-2048 public keys always require this chunking. A key published as a single string longer than 255 bytes will cause parsing failures at some DNS resolvers. Verification: check that the TXT record uses multiple quoted strings for RSA-2048 keys.

DMARC alignment failure with DKIM pass: DKIM verification passes (the signature is valid) but DMARC alignment fails because the DKIM signing domain (d= in the DKIM-Signature header) does not match the From: header domain. This occurs when the MTA signs with a different domain than the From: address uses. Resolution: configure PowerMTA's DKIM signing to use the same domain as the From: header, or use a subdomain of the From: header domain for signing (DMARC allows relaxed alignment for subdomains of the From: domain).

DKIM implementation is one of the foundational authentication requirements that makes all deliverability monitoring and reputation management meaningful. Without correct DKIM signing, ISP reputation signals cannot be accurately attributed to the sending domain, DMARC cannot be enforced, and the reputation building that inbox placement depends on cannot proceed. Getting DKIM right at the implementation level — correct key generation, DNS publication, PowerMTA configuration, and key rotation protocol — is the technical prerequisite for everything else in email infrastructure management that depends on authenticated domain attribution.

DKIM and Mailing List Transit

Messages forwarded through mailing list software or distribution lists frequently fail DKIM verification because the list processor modifies the message — adding a list footer, adding List-* headers, modifying the Subject line, or rewrapping the body. If the original DKIM signature covered the modified portions, the signature fails at the list recipients' ISPs.

The ARC (Authenticated Received Chain) protocol was developed to address this problem. ARC allows intermediate mail handlers (mailing list software, email forwarding services) to add their own authentication seal that records the authentication status of the message when they received it, before they modified it. Receiving servers that support ARC can then evaluate the original authentication status from the ARC seal even if the original DKIM signature has been invalidated by the intermediate modification. ARC support is growing among major ISPs and is now recommended for all programmes that send through mailing lists or forwarding services.

For direct sending programmes without mailing list transit, ARC is not required — DKIM signing and DMARC alignment are sufficient. For programmes that use list distribution or have recipients who forward messages through mailing list software, understanding ARC and ensuring that the intermediate list processors are correctly implementing ARC sealing prevents the deliverability problems that mailing list DKIM failures cause.

Verifying DKIM Implementation

Before deploying a DKIM configuration to production, verification that the signing and DNS publication are correct prevents authentication failures from reaching ISPs. The verification tools and checks:

DNS record verification: dig TXT selector._domainkey.yourdomain.com should return the TXT record with the public key. The p= tag contains the base64-encoded public key. The k= tag specifies the key type (rsa or ed25519). The v=DKIM1 tag confirms it is a DKIM record. For RSA-2048 keys, the TXT record should contain multiple quoted strings — if the entire key is in a single string longer than 255 characters, it will cause DNS parsing failures at some resolvers.

Test message signing verification: Send a test message to a Gmail address, then open the message in Gmail and view the original message source (three-dot menu > "Show original"). The Authentication-Results header will show dkim=pass if signing is correct, or dkim=fail with a reason if it is not. The reason field in a DKIM failure header (body hash mismatch, key not found, etc.) identifies the specific failure mode.

mail-tester.com: This free tool sends a test message through the user's MTA and evaluates DKIM signing, DMARC alignment, SPF, and several other authentication and content checks. It provides a clear pass/fail for each authentication component and identifies specific configuration issues when failures occur. Running a mail-tester check before deploying a new DKIM configuration to production is a reliable way to catch configuration errors before they affect production sending.

DMARC aggregate reports: Once a domain has DMARC enabled and the dkim implementation is in production, aggregate reports (rua= reports) from ISPs provide the fullest verification of DKIM alignment in production conditions. The aggregate reports show, per sending source, how many messages passed DKIM alignment and how many failed. A source that shows consistent DKIM failures in the aggregate reports has a configuration problem that the pre-deployment verification missed — typically an intermediate relay that modifies messages, or a sending service that is not signing with the correct domain.

Multiple Sending Domains: DKIM Selector Strategy

Programmes that send from multiple domains — a primary brand domain, a transactional subdomain, a separate marketing subdomain — need DKIM keys and DNS records configured for each. The selector naming strategy for multi-domain environments should be consistent enough to be manageable but distinct enough to identify the purpose of each key.

A clear selector naming convention: pmta-2022-04 (MTA identifier + year + month of key generation). This convention makes key age immediately visible from the selector name, facilitates the key rotation schedule (selectors more than 12 months old are candidates for rotation), and identifies which MTA the key is used on (useful when multiple MTAs sign for the same domain). The selector should not contain sensitive information about the infrastructure — it is publicly visible in every outgoing message's DKIM-Signature header.

For each domain, document the active selector(s), the key generation date, the scheduled rotation date (12 months after generation), and the private key file location. This documentation, maintained as a simple spreadsheet or infrastructure wiki page, is the operational record that makes key rotation a scheduled, planned event rather than a reactive response to expired or compromised keys. DKIM key management without documentation is a common source of authentication problems when keys are rotated without following the correct four-step protocol, or when keys expire at systems that have a maximum age policy for DKIM keys.

DKIM is the authentication mechanism that connects sending behaviour to sending domain in ISP reputation models. Getting it right — correct key generation, properly formatted DNS records, correct PowerMTA configuration, systematic key rotation, and DMARC aggregate report monitoring to verify alignment — is the foundational authentication work that makes all other deliverability management meaningful. Without it, reputation signals cannot be correctly attributed, DMARC cannot be enforced at policy levels that provide protection, and ISP postmaster tools cannot provide accurate per-domain data. It is worth implementing correctly once and maintaining systematically thereafter.

DKIM Header Canonicalization in Depth

The canonicalization algorithm specified in the DKIM-Signature header (the c= tag) determines how headers and body are normalized before hashing and signing. The two options — simple and relaxed — differ in how they handle whitespace, line endings, and header formatting variations that can occur between signing and verification.

Simple canonicalization is strict: it requires the signed content to be identical at signing and verification time, with no modifications. Any change — an added trailing space, a changed line ending, a folded header — breaks the signature. Simple canonicalization is appropriate when the signing MTA is also the final delivery MTA with no intermediate relays that might modify the message. In practice, this is rarely the case for commercial email programmes that use load balancers, content filters, or intermediate relays.

Relaxed canonicalization normalizes headers (lowercases header names, folds header whitespace, removes trailing whitespace) and normalizes the body (removes trailing whitespace per line and normalizes trailing blank lines). This normalization means that minor formatting variations introduced by transit systems do not break the signature. Relaxed canonicalization is the correct choice for production commercial sending where messages may pass through intermediate systems before final delivery.

The relaxed/relaxed specification in PowerMTA's DKIM configuration (header canonicalization / body canonicalization) applies relaxed normalization to both headers and body. This is the production default that should be used in all commercial sending configurations. Simple/simple is appropriate only for highly controlled environments where the sending MTA delivers directly to the receiving MTA without any intermediate processing — a configuration that is uncommon in practice.

DKIM Length Limits and the l= Tag

The DKIM specification includes an optional l= body length tag that limits the signed portion of the message body to a specified byte count. Only the first l= bytes of the body are included in the signature; content beyond that length is not signed and can be modified without breaking the signature. This was intended to allow forwarding services to append content (mailing list footers) without invalidating the signature — but it creates a significant security vulnerability: any unsigned portion of the message can be replaced with spam or malicious content while maintaining a valid DKIM signature.

The l= tag should never be used in production DKIM configurations. Its security implications outweigh its convenience for mailing list forwarding — and the ARC protocol provides a better solution to the mailing list transit problem without the security risk. If the PowerMTA DKIM configuration template being used includes an l= tag, remove it. Verify that no l= tag appears in outgoing DKIM-Signature headers by checking the raw message source of a test message.

DKIM implementation is a system with enough complexity in its operational details — key management, DNS format requirements, canonicalization choices, selector strategy, failure mode diagnosis — that a brief theory-level understanding leaves significant gaps between knowing what DKIM does and knowing how to make it work reliably in production. The operational details in this note bridge those gaps: the specific configuration, the rotation protocol, the verification steps, and the failure modes cover the implementation knowledge that theory does not provide. Apply them systematically, verify with the tools described, and maintain the key documentation that makes rotation a managed process rather than an ad-hoc event. DKIM, implemented correctly once, is a reliable foundation that requires only periodic maintenance rather than ongoing attention.

Infrastructure Assessment

Our managed infrastructure includes DKIM configuration verification during onboarding, annual key rotation as standard practice, and DMARC aggregate report monitoring to confirm that DKIM alignment is passing correctly for all sending sources. Request assessment →