A signature naming a selector with no usable key behind it produces permerror or no key for signature. Four different situations produce it, and one DNS query separates them.
Four causes, one query
| What the query returns | Cause | Fix |
|---|---|---|
| NXDOMAIN | The selector was never published, or was deleted | Publish it, or find out why the signer is using a selector you do not know about. |
A record with p= empty | The key is revoked | Intended, if you revoked it. If not, someone revoked a key that is still in use. |
| A CNAME whose target is NXDOMAIN | Dangling delegation — the vendor tore down their side | Remove the CNAME, or re-establish the delegation. |
| A record that will not parse | Malformed: a stray space in a split TXT, a truncated key | Re-publish. Check the answer, not the console. |
The dangling delegation
This is the one that is hardest to notice, because the CNAME resolves perfectly well and only the far end is missing. Fastmail has one on its own domain:
mesmtp.fastmail.com.dkim.fmhosted.com.
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN
Here it is harmless: the selector is a legacy one and nothing signs with it. The general case is not harmless. A dangling _domainkey CNAME pointing into a provider where anyone can claim a name is a takeover — whoever claims it can publish a key and sign mail as your domain, with an aligned d= and a valid DMARC pass.
The method
# 1. What selector is the signature claiming? # read s= from the DKIM-Signature header # 2. Ask for it, from a resolver you do not control dig +short TXT <selector>._domainkey.<d> @1.1.1.1 # 3. If the answer is a CNAME and nothing else, chase it dig +short TXT <target> # 4. If NXDOMAIN at either step, you have your answer
Query the d=, not the From domain
The key lives under the domain in d=, which is not necessarily the domain in the From header. Querying the wrong one returns NXDOMAIN and sends you looking for a missing record that was never supposed to be there.