What DKIM no key for signature and dkim=permerror mean, how to find the key record from s= and d=, the missing CNAMEs, split TXT strings, revoked keys and DNS errors behind it, and how to fix and verify it with dig.
Home › Guides › DKIM no key for signature
Last updated 18 October 2026
A DKIM no key error means the receiving server tried to fetch the signer's public key from DNS and couldn't use what it got back. The key always lives at <selector>._domainkey.<domain>, built from the s= (selector) and d= (signing domain) tags of the DKIM-Signature header. Either no record exists at that name, the record can't be parsed, the key was revoked with an empty p=, or DNS didn't answer.
The fix, in order:
s= and d= from the failing message.s._domainkey.d with dig, nslookup or Resolve-DnsName.google._domainkey TXT record, or your sending service's record, copied exactly.RFC 6376 section 6.1.2 lists what a verifier does when it gets the public key. The parts that produce no key style errors are:
| What happened in DNS | RFC 6376 status (explanation) |
|---|---|
| The query got no response | The verifier MAY return TEMPFAIL (key unavailable) and try again later. |
| No key record exists at the name | The verifier MUST return PERMFAIL (no key for signature). |
| A record exists but isn't valid key syntax | PERMFAIL (key syntax error). Malformed key records MUST be ignored. |
The key record's h= doesn't include the signature's hash algorithm | PERMFAIL (inappropriate hash algorithm). |
The p= tag is empty | PERMFAIL (key revoked), treated as a failed signature check. |
The key doesn't suit the signature's a= and k= | PERMFAIL (inappropriate key algorithm). |
PERMFAIL is a permanent error and the signature shouldn't be reconsidered; TEMPFAIL means it couldn't be verified this time but may be tried again (RFC 6376 sections 3.9 and 6.1). The words in brackets are not fixed strings: the RFC says the explanation is not normative and is there only for clarification.
Receivers write the result into the Authentication-Results header using one of the DKIM result values in RFC 8601 section 2.7.1:
| Result | Meaning (RFC 8601) | Relevance to a key problem |
|---|---|---|
none | The message was not signed. | Not a key problem: no DKIM-Signature header was found. |
pass | Signed, and the signature passed verification. | The key was found and worked. |
fail | Signed, but the signature failed verification. | Some receivers use this for a missing or revoked key, with a comment saying so. |
policy | Signed, but some aspect of the signature wasn't acceptable to the receiver. | The receiver's own rules (for example about algorithms or key length). |
neutral | Signed, but the signature had syntax errors or couldn't be processed; also used for other failures not covered elsewhere. | Some receivers use it for records they can't parse. |
temperror | A transient error, such as a temporary inability to retrieve a public key. A later attempt may produce a final result. | DNS timed out or returned an error for the key name. |
permerror | An unrecoverable error; a later attempt is unlikely to produce a final result. | The usual result for no key, a revoked key or a key syntax error. |
The wording varies by receiver. One may show dkim=permerror, another dkim=fail or dkim=neutral with its own comment in brackets about the key, so don't search headers for one exact phrase. An illustrative example:
Authentication-Results: mx.receiver.example; dkim=permerror (no key for signature) header.d=example.com header.s=s2024; spf=pass smtp.mailfrom=example.com; dmarc=pass header.from=example.com
Here DMARC still passes only because SPF passed and aligned. A signature that can't be verified doesn't help DMARC, so once the message is forwarded and SPF fails, DMARC fails too.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s2024; h=from:to:subject:date:message-id; bh=<base64 body hash>; b=<base64 signature>
d= is the signing domain and s= the selector. Both are required, and the verifier uses them (with q=, which defaults to dns/txt) to look up the key (RFC 6376 sections 3.5 and 3.6).<s>._domainkey.<d>. With d=example.com and s=s2024 that is s2024._domainkey.example.com. A selector can contain periods, which become extra DNS labels: RFC 6376 section 3.6.2.1 gives s=foo.bar and d=example.com as foo.bar._domainkey.example.com.header.d is the d= value of the signature that was checked, and many receivers also report the selector as header.s (RFC 8601 registers it as a reportable property). If header.s is missing, take s= from the matching DKIM-Signature header.d= isn't always your domain. A sending service that signs with its own domain keeps the key in its own DNS zone, and only the service can fix it. For DMARC you want a signature whose d= aligns with your From domain; see the DMARC alignment guide.The Email Header Analyzer lists every DKIM signature with its d= and s=, next to the receiver's results.
s2024._domainkey.example.com.example.com. New records also take time: Google says DKIM authentication can take up to 48 hours to start working after you add the key, and Microsoft says detecting new DKIM CNAMEs takes a few minutes or possibly longer.selector1._domainkey and selector2._domainkey, pointing at Microsoft's targets. Custom domains added since May 2025 use targets like selector1-contoso-com._domainkey.contoso.n-v1.dkim.mail.microsoft (custom domain with dashes, your initial *.onmicrosoft.com prefix, and a partition character Microsoft assigns); older domains use selector1-contoso-com._domainkey.contoso.onmicrosoft.com. Both formats can't coexist for the same selector, so copy the values your tenant shows instead of building them by hand. A typo in the target, or a CNAME deleted after signing was turned on, leaves receivers with no key. See DKIM for Microsoft 365.google, so the TXT record name is google._domainkey and the value has the form v=DKIM1; k=rsa; p= followed by the key generated in the Admin console. If the domain already had a google key for another service, you may have chosen a different prefix; the selector in s= tells you which. See SPF, DKIM and DMARC for Google Workspace.p= means the key has been revoked; verifiers return PERMFAIL (key revoked), and there is no defined difference between a revoked key and a removed one. That is correct for a retired selector, but if mail is still being signed with it, the signer needs a new key and selector.v=, if present, MUST be DKIM1 and the first tag, and records with any other v= value are discarded; k= defaults to rsa and must match the kind of key in p= and the algorithm in the signature's a=; tag names are case-sensitive; a tag that appears twice makes the whole tag list invalid; and a semicolon can't appear inside a value. A record that breaks these rules is ignored as malformed.dkim=temperror. If it keeps happening, check that every name server for the domain answers for the _domainkey name.Open the received copy (view the original or the message source) and paste the headers into the Email Header Analyzer. Note the DKIM result and comment from the receiver's own Authentication-Results line, and the d= and s= of the signature that failed. Build the record name <s>._domainkey.<d>.
# Linux or macOS dig +short TXT s2024._domainkey.example.com dig TXT s2024._domainkey.example.com +noall +comments +answer dig +short CNAME selector1._domainkey.contoso.com dig @1.1.1.1 +short TXT google._domainkey.example.com dig @8.8.8.8 +short TXT google._domainkey.example.com # Windows (Command Prompt or PowerShell) nslookup -type=TXT google._domainkey.example.com Resolve-DnsName -Name selector1._domainkey.contoso.com -Type CNAME Resolve-DnsName -Name selector1._domainkey.contoso.com -Type TXT
The second dig command prints the response status (NOERROR, NXDOMAIN or SERVFAIL). For a Microsoft 365 selector, the CNAME query shows where the name points and the TXT query follows the CNAME to the key. How to read the result:
| What you get | What it means |
|---|---|
NXDOMAIN, or NOERROR with no answer | No record at that name: the no key for signature case. Publish it, or fix the name. |
| A CNAME, but no TXT record at its target | The CNAME points nowhere useful (a typo, or the provider no longer has that key). Copy the target again from the provider. |
v=DKIM1; k=rsa; p= with nothing after p= | The key is revoked. Sign with a selector that has a live key. |
| Several quoted strings in one answer | Normal for a long key. Check that the joined text is the full key, in order, with no stray quotes inside. |
| Two or more TXT records | Results are undefined. Delete all but the correct one. |
SERVFAIL or a timeout | A DNS problem, not a missing record; this is what causes temperror. Check the domain's name servers. |
| Different answers from different resolvers | A recent change that hasn't reached every resolver yet. Wait and check again. |
Get-DkimSigningConfig -Identity contoso.com | Format-List Name,Enabled,Status,Selector1CNAME,Selector2CNAME in Exchange Online PowerShell, or from the domain's DKIM details in the Defender portal (a status of CnameMissing means Microsoft can't see them yet). Create both CNAMEs, selector1._domainkey and selector2._domainkey. The DKIM for Microsoft 365 guide has every step.s=.p=, a wrong v= or k=, duplicate tags or a truncated key.s= as an extra selector (or enter the full selector host name). It shows whether a key is published, its length, and whether it was revoked.p= to revoke the key on purpose.dkim=pass with header.d set to your domain, and dmarc=pass. If DKIM now fails with body hash did not verify, the key is fine and something changed the message in transit: see how to fix DKIM body hash did not verify.Need SPF, DMARC and MX checks across a whole client list? Run the Bulk SPF / DMARC / MX Auditor on Apify ($2 per 1,000 domains).
Find published selectors with the DKIM Checker, decode a key record with the DKIM Record Explainer, read s=, d= and DKIM results with the Email Header Analyzer, check a new record across resolvers with the DNS Propagation Checker or query it with DNS Lookup. Related guides: DKIM for Microsoft 365, SPF, DKIM and DMARC for Google Workspace, DKIM body hash did not verify and DMARC fail with SPF pass (alignment).
The receiver looked up the public key at the selector._domainkey name built from the s= and d= tags of the DKIM-Signature header and found no key record there. RFC 6376 calls this PERMFAIL (no key for signature). Receivers report it as dkim=permerror, or as fail or neutral with a comment.
Not quite. In RFC 8601, fail means the signature was checked and failed verification, while permerror means it could not be verified at all because of an unrecoverable error, such as a missing or broken key record. Either way the signature does not count toward DMARC.
It depends on the provider and DNS caching. Google says DKIM authentication can take up to 48 hours to start working after you add the key, and Microsoft says detecting new DKIM CNAME records takes a few minutes or possibly longer. Resolvers may also keep an earlier answer cached for a while.
The key has been revoked. RFC 6376 says verifiers must treat a signature that uses it as failed and return PERMFAIL (key revoked), and there is no defined difference between a revoked key and a removed one. Sign with a different selector that has a live key.
temperror means the receiver could not fetch the key because of a temporary problem, such as a DNS timeout or server error, and a later attempt may work. permerror means the lookup gave a final answer that cannot be used. Repeated temperror results point to a problem with the domain name servers.
Runbooks, checklists and helpdesk templates: IT Admin Packs on Gumroad.