What DKIM actually proves
When your outbound mail server signs a message it hashes selected headers plus the body, encrypts that hash with a private key, and inserts a DKIM-Signature: header. The receiving server reads two tags out of that header — d= (the signing domain) and s= (the selector) — and fetches the matching public key from DNS at <selector>._domainkey.<domain>. If the signature verifies, the receiver knows the message was authorised by whoever controls that DNS zone and that the signed parts were not modified in transit.
That is a narrower claim than most people assume. DKIM says nothing about the visible From: address on its own — a spammer can sign their own mail with their own valid key. What makes DKIM useful is DMARC, which requires the d= domain to *align* with the From: domain. DKIM is also the half of authentication that survives forwarding: SPF breaks the moment a mailing list relays your message from a different IP, but a DKIM signature keeps verifying as long as nothing rewrites the signed headers or body.
Reading the record this tool returns
A DKIM key record is a TXT record made of semicolon-separated tags. A typical Google Workspace record looks like this:
google._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6T5sl..."| Tag | Meaning | What to check |
|---|---|---|
| v=DKIM1 | Version | Optional in RFC 6376 but expected by strict verifiers. Add it. |
| k=rsa | Key algorithm | rsa or ed25519. Anything else is a typo or a mangled record. |
| p=… | Base64 public key | Must decode to a valid SubjectPublicKeyInfo. An empty p= means the key is revoked. |
| t=y | Testing mode | Receivers must ignore failures. Remove once you are live. |
| t=s | Strict domain | The d= domain must equal the From: domain — subdomains cannot use this key. |
| h=sha256 | Allowed hashes | Never restrict to sha1 alone; RFC 8301 deprecates it. |
| s=email | Service type | Must include email or *, or the key is not used for mail. |
Read the full explanation of dkim checker results ↓Show less ↑
The tool decodes p= and derives the real modulus length from the key material rather than guessing from string length, so the reported key size is the size a verifier will actually use. 1024-bit RSA is the RFC 8301 floor and still verifies everywhere, but 2048-bit is the current norm. Below 1024 bits, several large receivers treat the signature as absent.
Selector discovery when you do not know the name
There is no way to list the selectors a domain publishes — DNS has no directory of subdomains, so you cannot enumerate _domainkey children. That leaves three approaches, in order of reliability.
- Read a real message. Send yourself mail from the domain, view the source, and find the
DKIM-Signature:header. Thes=tag is the selector andd=is the signing domain. This is authoritative — it is the selector receivers are actually using. - Check your provider's documentation. Google Workspace uses
googleby default, Microsoft 365 usesselector1andselector2(published as CNAMEs), Mailchimp usesk1, SendGrid usess1ands2, Zoho useszoho, Proton usesprotonmail. - Brute-force the common names. Leave the selector field blank here and the tool queries about 45 selectors seen across major providers. A hit is proof; a miss proves nothing, because a custom selector name will not be on any list.
s20260901. Always confirm against a real DKIM-Signature header before telling someone their DKIM is missing.Many providers publish the key as a CNAME rather than a TXT record — Microsoft 365 and SendGrid both do this so they can rotate keys without you touching DNS. Resolvers follow the CNAME transparently, so the tool still returns the final TXT record. If you see the key but your provider's console says "not configured", the CNAME target is usually the problem: it must match their value exactly, including the tenant-specific portion.
Common failures and how to fix them
The record exists but signatures still fail
If the key is published and valid, a dkim=fail verdict is almost always a *body hash* failure, not a key problem. Something modified the message between signing and verification: a mailing list appending a footer, an appliance rewriting URLs for click-tracking, a signature-adding gateway, or an antivirus scanner reformatting MIME parts. Run the message headers through the email header analyzer and look at which hop sits between the signing MTA and the verifying one.
Empty p= tag
A record of v=DKIM1; p= is a deliberate revocation. RFC 6376 defines it as "this key is no longer valid" — every signature made with it fails immediately. If you see this and did not intend it, your provider revoked the key during a rotation and the replacement selector was never published.
The TXT record was split incorrectly
A single DNS string cannot exceed 255 bytes, so a 2048-bit key must be published as multiple quoted chunks that the resolver concatenates. Some control panels insert spaces or newlines between chunks; base64 tolerates whitespace, but a control panel that inserts a literal \n or truncates at 255 characters will produce a key that decodes to garbage. The tool reports this as "p= decodes but is not a parseable public key".
Two TXT records at the same selector
If both an old and a new key sit at selector._domainkey, verifiers pick one non-deterministically and roughly half your mail fails. This is the single most common outcome of a botched key rotation. Rotate by publishing a *new selector*, waiting for the signing side to switch, then deleting the old selector — never by editing the record in place.
Checking DKIM from the command line
Everything this page does you can do with dig. Query the selector name directly and read the TXT answer:
# Fetch the key record for the "google" selector
dig +short google._domainkey.example.com TXT
# Query an authoritative nameserver directly, bypassing any resolver cache
dig @ns1.example.com google._domainkey.example.com TXT +noall +answer
# Extract p= and confirm the real key size (2048 bit RSA here)
dig +short google._domainkey.example.com TXT \
| tr -d '"' | tr -d ' \n' \
| sed -n 's/.*p=\([A-Za-z0-9+/=]*\).*/\1/p' \
| base64 -d | openssl rsa -pubin -inform DER -noout -text | head -1The last command is the one worth memorising: if openssl prints Public-Key: (2048 bit) the record is genuinely parseable. If it errors, the record is corrupt no matter how correct it looks in your DNS control panel. Use TXT record lookup if you want to see the raw chunking, and the deliverability test to check SPF, DKIM, DMARC, MX and PTR together.
Rotating keys safely
Rotate DKIM keys at least annually, and immediately if a private key may have been exposed. The safe sequence is: publish the new selector in DNS, wait for at least the old record's TTL plus a margin, switch the signing configuration to the new selector, verify with a live message, then wait a full week before deleting the old selector. That last wait matters — messages sitting in a receiver's queue or a mailing list's retry buffer will still be verified against the old key.