DKIM for WordPress email: how the signature works and how it fails

A WordPress site that sends mail from its own domain has to prove to receiving mail servers that the mail is really coming from the site. DKIM is one of three records that make that proof, and on most WordPress setups it is also the one actually doing the work. The record is a cryptographic signature the sending service attaches to every outgoing message, and the public key for verifying the signature lives in your DNS.

For an operator setting up email on a WordPress site, DKIM goes in alongside SPF and DMARC and is often the one worth getting right first. The signature survives when a reader forwards an email or when a mailing list relays it onward, which keeps the receiver’s trust intact across hops that would otherwise break authentication. The failure modes are specific (a key size that fits in DNS, a selector that matches what the provider signs with, a signed region that nothing modifies in transit) and once in place the record is low-maintenance.

What the record looks like

DKIM publishes a public key as a DNS TXT record at a specific subdomain: <selector>._domainkey.<yourdomain>. The selector is a short label chosen by the signing service; a domain can publish multiple keys for multiple senders by using different selectors. Postmark uses 20231218pm._domainkey.yourdomain.com; Amazon SES uses three CNAMEs that point at hashed selectors in SES’s own zone. The record itself looks like this:

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...

The three tags: version, key algorithm, public key material. RFC 6376 is the specification; §3 defines the signing process and §6 the verification algorithm.

The private half of the key lives on the signing server. The sender signs each outgoing message by computing a hash over the message body and a selected list of headers (From:, To:, Subject:, Date:, and typically a handful more), encrypting that hash with the private key, and attaching the result as a DKIM-Signature: header. The receiver fetches the public key from DNS, recomputes the hash, and compares.

How the signature survives, and when it does not

DKIM authenticates the message, not the connection. That is what makes it the one authentication record that passes through a forwarding hop intact: the signature travels with the headers, and a receiver re-verifying it on the far side of a forward will get a pass if nothing in the signed portion changed in transit.

The failure mode is that something in the signed portion did change. Three things cause it in practice:

  • A forwarder or mailing list rewrites the Subject: or body. Appending [LIST-NAME] to the subject or injecting a footer rewrites a signed region. The receiver’s hash does not match, and DKIM fails.
  • A relay normalises headers aggressively. Whitespace, line-wrap, or MIME-boundary changes can touch bytes the signature covered. Canonicalisation (c=relaxed/simple or c=relaxed/relaxed in the signature) controls how tolerant verification is of header whitespace changes, but it does not protect against body modification.
  • The DNS key disappears or rotates mid-flight. A key that was published when the message was signed but removed by the time the receiver verifies produces a temperror on the receiver side. On WordPress, this happens when operators rotate relay providers without leaving the old selector live for the propagation window.

The signature carries the sender’s d= tag (the signing domain) and s= tag (the selector). Both appear in the message headers; both are what the verifier uses to find the public key.

DKIM alignment and DMARC

A DKIM pass on its own tells the receiver that the message was signed by a server holding the key for whatever domain is in the d= tag. That is not necessarily the domain in the From: header the reader sees.

DMARC adds the alignment requirement. For DMARC to pass on DKIM, the d= tag on a valid DKIM signature must match (or be a subdomain of) the From: domain. Most transactional relays default to signing with their own domain (d=sendgrid.net, d=mailgun.org), which produces a valid DKIM pass that does not align. The fix is configuration: ask the provider to sign with a custom DKIM key on your domain, publish the key as the provider instructs, and the signature carries alignment. On WordPress, this is the step that often does not get done; a site sends through SendGrid with vendor DKIM, DMARC moves to p=quarantine, and legitimate mail starts landing in spam.

For DMARC with a p=reject policy, DKIM alignment is usually the practical path to a pass. SPF alignment on a transactional relay is harder to arrange because the envelope sender is typically the relay’s bounce address, which rarely aligns.

Key size and rotation

RFC 8301 (2018) deprecated 1024-bit RSA keys for new deployments; current practice is 2048-bit RSA. Gmail and Microsoft 365 flag 1024-bit keys as weak in their inbound diagnostics. The practical ceiling is DNS: a 2048-bit public key does not fit in a single 255-character TXT string, so providers split the key across multiple strings concatenated inside one record. Most DNS consoles handle the split transparently; a handful (older cPanel panels, a few registrar DNS editors) do not, and the symptom is a key that verifies locally but fails at Google and Microsoft.

Key rotation is the point most operators get wrong. Rotate by publishing a new selector first, waiting for propagation, switching the signing selector at the relay, and only then removing the old DNS record. A rotation that removes the old record before signed-in-flight mail reaches its receivers produces a window of hard DKIM failures that look to the operator like a provider outage.

What DKIM does not do

DKIM authenticates the signer, not the content’s truthfulness or the sender’s intent. A message passing DKIM can still be unwanted; the record proves provenance, not legitimacy.

DKIM does not authenticate the envelope sender (the SMTP MAIL FROM), which is what SPF covers. The two work on different parts of the message for different purposes, and DMARC requires alignment on either but not both.

DKIM also does not survive content modification by the signer. A WordPress plugin that filters outbound mail after the mailer has signed (unusual but possible with poorly-ordered action priorities on wp_mail) will break its own signature.

For the authentication records DKIM sits alongside, see SPF for WordPress email and DMARC for WordPress email. For the delivery chain the three records govern, how email works on WordPress is the mental model. The full outbound DNS walkthrough is at set up DNS for WordPress email.

DKIM for WordPress email: how the signature works and how it fails details
Short Definition
DKIM (DomainKeys Identified Mail) is a cryptographic signature attached to each outgoing message, verifiable against a public key published in DNS. It lets receivers confirm the message was not altered in transit and originated from a server the domain authorised to sign on its behalf.
Related Terms
spf, dmarc, email-explained-from-first-principles