DKIM Record Example Dissected: Every Tag, Explained
Most explanations of DKIM stay abstract - "a cryptographic signature verified against DNS" - and never show you the artifact itself. So here is a real dkim record example of the shape you will find in any configured domain's DNS, followed by a field-by-field dissection of it, the signature header it validates, and the selector mechanism that ties the two together.
The one-sentence model first: your sending server holds a private key and signs every outgoing message with it; the matching public key is published in your DNS; receivers fetch the public key and verify the signature. A valid signature proves the message body and key headers were not altered in transit and that the signer controls your domain's DNS - which is the property SPF cannot provide, because SPF breaks the moment mail is forwarded while a DKIM signature travels intact.
A real dkim record example, in full
A DKIM public-key record is a TXT record at a very particular hostname:
google._domainkey.example.com. TXT
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArZx7Qw3D
4kFhH8mV2n9L5tYcO6pXae1RgIhNqUw0jM7fBv6sK2dTzXluEHnP4oJgW8yCi5rDkA3S
9bfeVmZQxNtF0uGpJhcTsE1LqYvR2wnO7dK4iXaU6MpBz8CHgSlyD5MotIrfWq1v3ke
...remainder of the Base64 public key...
QIDAQAB"
Three structural facts before the tags. The hostname is always <selector>._domainkey.<domain> - the literal string _domainkey is fixed by the standard, while the selector (google here) is chosen by whoever generated the key. The value is one logical string; because DNS TXT strings cap at 255 characters and a 2048-bit key runs longer, the value is usually split into multiple quoted chunks that receivers concatenate - the quotes are packaging, not content. And unlike SPF, a domain can hold many DKIM records simultaneously, one per selector, which is what makes key rotation and multiple sending services painless.
The tags, one by one
| Tag | Example | Meaning |
|---|---|---|
v= |
DKIM1 |
Record format version. Always DKIM1; if present it must be first. |
k= |
rsa |
Key algorithm - rsa is standard, ed25519 the newer alternative. Optional; rsa is the default. |
p= |
MIIBIjANBg... |
The Base64 public key - the payload. An empty p= is meaningful: it announces the key is revoked. |
t= |
y or s |
Flags: y marks testing mode (verifiers treat failures leniently - never leave it on); s forbids subdomain use of the key. |
h= |
sha256 |
Restricts acceptable hash algorithms. Rarely set. |
s= |
email |
Service type the key applies to. Default *; effectively always email. |
n= |
free text | Human notes for admins. Ignored by verifiers. |
In practice, most real records contain only v=, k=, and p= - the minimal viable record is v=DKIM1; k=rsa; p=<key>. Everything else is a special case, and the two special cases worth remembering are the empty p= (deliberate revocation, not a broken record) and a forgotten t=y (your signatures pass only out of the receiver's charity).
The other half: the signature header it validates
Every DKIM-signed message carries a DKIM-Signature header, and reading one tells you exactly where to find the record above:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=google; h=from:to:subject:date:mime-version;
bh=Kx0lQfRt2P8mWvJ3nYca7Ue1Ss9iBzDhoG4NpLqM6EA=;
b=dGhpcyBpcyBub3QgYSByZWFsIHNpZ25hdHVyZSBidXQgaXQgbG9va3MgbGlrZSBvbmU...
The d= tag names the signing domain and s= names the selector: receiver-side, verification starts by fetching TXT at s+._domainkey.+d - google._domainkey.example.com, our record. h= lists which headers were signed (From is mandatory), bh= is the body hash, b= the signature itself, and c=relaxed/relaxed the canonicalization - how much whitespace-and-case tolerance verification allows. When you want to know your own selector and can't find it in your provider's dashboard, this header in any delivered message is the authoritative answer.
DMARC adds one more reading of the same header: for DKIM to count toward DMARC, d= must align with the domain in the visible From line. A platform signing with its own d=platform.example produces a valid DKIM pass that still fails DMARC alignment for you - which is why serious platforms have you publish keys (or CNAMEs) under your domain.
What you'll actually paste: TXT vs CNAME
Providers deliver DKIM setup in two shapes. Google Workspace has you generate the key in the Admin console and paste a TXT record at google._domainkey yourself. Microsoft 365 instead gives you two CNAME records - selector1._domainkey and selector2._domainkey, pointing into Microsoft's own DNS - and most sending platforms use the same CNAME pattern with two or three selectors.
The CNAME design is not laziness; it is key custody. Your CNAME delegates the lookup to the provider's zone, so the provider can rotate the actual keys on their side - regularly, as good practice demands - without ever asking you to touch DNS again. Two selectors exist precisely so one can hold the live key while the other stages its replacement. If your platform offers CNAMEs, use them; hand-pasted TXT keys are for providers (like Google) that manage rotation through their own console.
Self-hosters generating their own keys - with opendkim-genkey or a library equivalent - inherit the rotation duty themselves: mint a new key under a fresh selector, publish it, switch signing over, leave the old record up for a week or two so in-transit mail still verifies, then blank its p= to revoke. Dated selectors like 2026a make the bookkeeping self-documenting, and an annual rotation is the commonly cited floor for good hygiene.
Checking a record, and the failures worth knowing
To inspect any domain's key: dig TXT <selector>._domainkey.<domain> (or nslookup with -type=TXT). Verify end-to-end by sending a message to a Gmail address and reading Show original: DKIM: PASS with the signing domain beside it.
The recurring failures are mundane. A truncated p= from a copy-paste that dropped the key's tail - signatures fail verification everywhere, visibly. Mangled string splitting, where a DNS panel inserted quotes mid-key incorrectly. Wrong selector - the record sits at s1._domainkey while messages sign with s=selector1. A stale key after switching platforms, so old signatures verify but new mail signs against a record that no longer matches. And 1024-bit keys surviving from old setups: still verifiable, but 2048-bit has been the recommended strength for years and some receivers score short keys down. Every one of these is diagnosable in two minutes with the dig command and one Show-original check - which is exactly the pair of habits this record rewards.
Frequently asked questions
What does a DKIM record look like?
A TXT record at
Where in DNS does a DKIM record go?
At the hostname formed by your selector plus ._domainkey - for example google._domainkey.example.com. The selector is named by whoever generated the key and appears as the s= tag in each message's DKIM-Signature header.
Should DKIM be a TXT record or a CNAME?
Whichever your provider specifies. Google Workspace uses a pasted TXT key; Microsoft 365 and most sending platforms give you CNAMEs that delegate to their zone so they can rotate keys without you touching DNS again.
Can a domain have multiple DKIM records?
Yes - one per selector, and that is by design. Multiple selectors let several services sign for the same domain and allow key rotation, unlike SPF where a second record is an error.