DKIM (DomainKeys Identified Mail) is a digital signature that the sending domain adds to every email. It lets the receiving server check that the message really comes from that domain and that nobody altered it in transit, which limits spoofing and weighs on deliverability. The IETF standardized it in 2007 (RFC 4871) and revised it in 2011 (RFC 6376).
What does a server actually check when it writes dkim=pass in a message header? It finds that a signature attached by the sending domain matches a public key published in that domain’s DNS, and that the body did not change during transit. Nothing else. An emailing dashboard that shows “DKIM OK” therefore says nothing about the list you target or the reputation of the IP.
Since February 1, 2024, Google requires SPF, DKIM and DMARC authentication from senders who send more than 5,000 messages a day to Gmail. This guide reads a signature field by field, shows the record to publish, then covers the test and the usual causes of failure.
The DKIM-Signature header, field by field
Open the original of a received email and the header looks like this (illustrative values, signature shortened).
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s1; t=1760000000; h=from:to:subject:date:message-id; bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=; b=Zm9ybWF0IGQnaWxsdXN0cmF0aW9u...
Each tag follows a definition in RFC 6376, published by the IETF in September 2011.
| Tag | Example value | Role |
|---|---|---|
| v | 1 | Version of the DKIM specification |
| a | rsa-sha256 | Signing algorithm: RSA with a SHA-256 hash |
| c | relaxed/relaxed | Canonicalization of headers and body (tolerates extra spaces and line breaks) |
| d | example.com | Signing domain, compared with the From domain for DMARC alignment |
| s | s1 | Selector, which names the key to fetch from DNS |
| t | 1760000000 | Unix timestamp of the signature (October 9, 2025 at 08:53 UTC) |
| h | from:to:subject:date:message-id | List of headers covered by the signature |
| bh | 47DEQpj8… | Hash of the message body |
| b | Zm9ybWF0… | Signature, computed over the headers listed in h |
Two tags are often confused. bh holds the body hash, while b is the signature itself, computed over the headers in h and over the DKIM-Signature header (with b empty). A SHA-256 hash is 32 bytes, which makes 44 base64 characters in bh. Change the body by a single byte and bh breaks; change a signed header and b breaks. The rsa-sha1 algorithm has been prohibited since RFC 8301 (January 2018), so a modern signature shows rsa-sha256. The optional l tag limits the signed part to a number of body bytes, which leaves room for content appended after the covered portion; RFC 6376 describes the abuse in section 8.2.
From signature to verification: who does what
The common phrasing (“encrypt the hash with the private key”) blurs the roles. In practice the sequence runs in four steps.
- The sending server (MTA) canonicalizes the body, computes its SHA-256 hash and places it in bh.
- It hashes the headers listed in h plus the DKIM-Signature header itself, then signs the result with its private key. That signature becomes b. The private key never leaves the sending server.
- The receiving server reads d and s, queries DNS for s._domainkey.d and retrieves the public key. The sender plays no part at this stage.
- The receiver recomputes the body hash and compares it with bh, then verifies b with the public key. When both checks agree, the result is dkim=pass.

Selector and TXT record: where the key is published
The selector, the value of the s tag, builds the DNS name the receiver will query: s._domainkey.d. For s=s1 and d=example.com, the lookup targets s1._domainkey.example.com, where a TXT record is expected.
s1._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
The v tag announces the version, k the key type and p the public key in base64. An empty p marks a revoked key. The start of the value gives away the size: MIIBIjANBgkq… is a 2048-bit RSA key, MIGfMA0GCSqG… a 1024-bit one.
RFC 8301 requires signers to use RSA keys of at least 1024 bits and recommends 2048 bits. A 1024-bit key takes about 216 characters. A 2048-bit key takes 392 characters in base64, which exceeds the 255-character limit of a DNS string, so the record must be split into several quoted strings. Some DNS interfaces do this for you and others do not. Each sending tool (Google Workspace, a CRM, an ESP) gets its own selector under the same domain, which is why a zone often holds several.
One last trap: depending on the interface, the “host name” field expects s1._domainkey alone or the full name. Typing the full name where the domain is appended automatically produces s1._domainkey.example.com.example.com, which the receiver cannot find. This record lives in the same zone as the other sender DNS records (SPF, MX, DMARC): one interface to edit, one zone owner to identify.
Setting up DKIM in Google Workspace, Microsoft 365 or an ESP
In Google Workspace, the path goes through the Admin console: Apps > Google Workspace > Gmail > Authenticate email. The “Generate new record” button creates the key pair; you copy the TXT value into the DNS zone, then start the authentication. After Gmail is activated, the key shows up in the console only after 24 to 72 hours, according to Google Workspace’s help documentation.
Microsoft 365 (Office 365 in older documentation) works differently. The Microsoft Defender portal (security.microsoft.com), under “Email authentication settings”, provides two selectors named selector1 and selector2, to publish as CNAME records pointing to records hosted by Microsoft, following the pattern selector1-example-com._domainkey.tenant.onmicrosoft.com. Only one of the two selectors signs at a time while the other waits for the next rotation, so the switch happens without downtime.
With an ESP, the platform gives you TXT or CNAME records to copy. Until your DNS zone contains them, the ESP signs with its own domain: the test shows dkim=pass, yet the d domain does not match the From, so the signature does not count for DMARC. The same happens with an outbound gateway that appends a footer: the body changes after signing, a case Google Workspace’s documentation calls out explicitly.
Testing DKIM: reading Authentication-Results
Send a test message to a Gmail mailbox, open the three-dot menu on the message and choose Show original. Gmail displays “DKIM: PASS” with the domain, then details the verdict in the Authentication-Results header.
Authentication-Results: mx.google.com; dkim=pass header.i=@example.com header.s=s1 header.b=Zm9ybWF0; spf=pass smtp.mailfrom=example.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com
In the dkim line, header.s gives the selector used, header.i the signing identity and header.b the first characters of the signature. The format comes from RFC 8601. The possible verdicts are pass, fail (invalid signature), none (no signature), neutral, temperror and permerror (temporary or permanent DNS error).
To isolate a DNS problem before sending anything, the command dig +short TXT s1._domainkey.example.com returns the published value; an online DKIM test tool (dkim lookup, dkim checker) runs the same query using the s value from the header.
Why a DKIM signature fails
A dkim=fail almost always comes down to one of these cases.
- The body changed after signing, for example a footer added by a relay. bh no longer matches.
- The selector cannot be found: a typo, or a host name with the domain appended twice.
- The public key is truncated: an unsplit 2048-bit TXT record.
- The private key was regenerated on the provider side without a DNS update.
- The message passes through a mailing list or a forward that rewrites the subject or adds a footer: the original signature no longer covers the content received.
- The signature passes but the d domain differs from the From domain: DMARC rejects it for lack of alignment.
DMARC alignment and Gmail and Yahoo requirements
Yahoo has applied its requirements since February 2024: its Sender Hub asks for the From domain to align with the SPF domain or the DKIM domain (Yahoo best practices). In relaxed mode, the default, d=news.example.com aligns with a From address at example.com; strict mode (adkim=s) requires the exact identity, per RFC 7489 from 2015. A message sent by an ESP with d=mailer.esp-example.com and a From of @example.com therefore fails DKIM alignment; if the Return-Path also belongs to the ESP, SPF fails too. Under a DMARC policy of p=reject, a message with neither SPF nor DKIM aligned is rejected.
Thresholds differ by volume. For any sender to Gmail, Google asks for SPF or DKIM since February 1, 2024; above 5,000 messages a day, both SPF and DKIM are required. Google also asks for a published DMARC record (p=none is enough), valid forward and reverse DNS records and a TLS connection, and message format follows RFC 5322. On reputation, the page aims for a spam rate under 0.10% in Postmaster Tools and says never to reach 0.30%. Yahoo asks for SPF and DKIM together, a DMARC record of at least p=none and the same 0.3% ceiling. SPF alone no longer passes for high volume.
Key rotation
Replacing a key without downtime takes two selectors, for example s1 then s2. Publish the new key under s2 while s1 still signs, switch signing to s2, then leave s1 in DNS long enough for queued messages to be verified. Removing it too early causes dkim=fail on legitimate sends, which people wrongly take for a DNS outage.
What DKIM does not verify
A spammer can sign their sends with their own domain and get dkim=pass: the signature proves where the message came from and says nothing about the content or the quality of the list. A perfectly signed domain that writes to dead addresses piles up hard bounces, and its sender reputation suffers all the same.
Before your next campaign, run a sample of your list through an email verification check: the result tells you how many invalid addresses the database holds before they surface in Postmaster Tools.
