Bali, Indonesia
Insights

Why a DKIM Record That Looks Saved Still Fails When You Query It with dig

October 20, 2026
0:00
You paste the DKIM record your mail server or email service gave you, the DNS panel says it was saved, and it sits in the zone list looking normal. Then a checker says no DKIM record was found, or the message headers at the receiving end show DKIM failing. It's tempting to think the panel is lying or DNS is slow. More often the panel is showing exactly what you typed, and what you typed is not what a verifier looks up. The only version of the record that matters is the one returned by your domain's authoritative nameservers at one specific name. The misconceptions below are the ones that keep people from checking that name directly. At the support desk, this usually comes up when a customer says "I already added DKIM" and the panel agrees with them.
This feels true because the panel is the place where you manage DNS, so a saved entry there looks like a published entry. But a DNS panel only shows records stored in its own system. Whether anyone ever reads them depends on which nameservers the domain is delegated to at the registrar. If the domain points to a different DNS provider, a CDN, or an old hosting account, you can add DKIM records to the panel all day and no verifier will ever see them. This happens a lot after migrations, when the zone exists in two places and only one of them is live. Caching adds a second layer. If you or a checker queried the DKIM name before the record existed, a recursive resolver may cache that negative answer for a while. A fresh query to that same resolver can keep saying the name doesn't exist even after the record is correctly published. That's why the reliable test is to ask the authoritative nameserver directly, not whatever resolver your laptop happens to use.
A DKIM record lives at a name built from two parts: the selector and the signing domain. When a receiving server checks a signature, it reads the s= tag (the selector) and the d= tag (the domain) from the DKIM-Signature header. It then looks up a TXT record at selector._domainkey.domain. For a selector called selector1 on example.com, that name is selector1._domainkey.example.com. So it feels natural to type selector1._domainkey.example.com into the host or name field. Many DNS panels, though, treat that field as relative to the zone and append the domain for you. The record ends up at selector1._domainkey.example.com.example.com. The panel's list may even hide this by showing only the part you typed, so everything looks right. The verifier queries the correct name, finds nothing, and DKIM fails with something like "no key" or "record not found". Meanwhile the record is sitting one label too deep where nobody looks. Panels differ here. Some expect only selector1._domainkey. Some accept a full name ending with a trailing dot, which in standard zone file syntax marks a name as fully qualified. Some strip or ignore the dot. Rather than guess, save the record and then query both the expected name and the doubled name. Whichever one answers tells you how your panel behaves. The same trap applies when an email service asks you to create a CNAME for DKIM instead of a TXT record. The host field is appended the same way, so a CNAME can end up doubled too.
Key generators often hand you the public key as one long line, so it seems logical that DNS should store it the same way. And when a panel splits it, that looks like corruption. The actual rule is that a single character-string inside a TXT record can hold at most 255 bytes. A TXT record is allowed to contain several of these strings, and DKIM verifiers join them back together with nothing in between before reading the key. A 1024-bit key usually fits inside one string. A 2048-bit key's base64 value is roughly 400 characters, so it has to be split into at least two strings, whether you do it or the panel does. Splitting is fine. What breaks DKIM is splitting done badly. Common patterns include:
  • Literal quote characters ending up inside the value, because the record was pasted with quotes from a generator and the panel added its own. The key then contains characters that aren't valid base64.
  • The value being cut short because a panel field has a length limit and truncates without warning. The record exists, but the key is incomplete and won't decode.
  • Pieces from different copy attempts, or a missing chunk in the middle, where the string boundaries don't line up with the original key.
  • Extra spaces or line breaks inside p=. The DKIM spec allows some whitespace there, but not every verifier is equally forgiving, so it's safer to keep the key clean.
None of this is visible from a "record saved" message. You have to look at what DNS actually returns.
Getting a TXT answer at the right name is necessary, but it only proves the public key is published. DKIM passes when the public key in DNS matches the private key that signed the message, and when the signature points at that record. A few ways this goes wrong even with a perfect-looking record. The mail server may be signing with a different selector than the one you published, for example after a key regeneration that created a new selector. The private key may have been rotated on the server while DNS still holds the old public key. Or the d= domain in the signature may not be the domain you think, which matters for DMARC alignment as well as for which zone holds the key. This is where the DNS check hands off to the message itself. The DKIM-Signature header shows the selector and domain that were used, and the receiving server's Authentication-Results header tells you whether verification passed and why not if it didn't. If you need that side of it, Reading Authentication-Results Headers to Fix DMARC Alignment covers it.
The whole check fits in a few read-only dig queries. dig is part of the DNS utilities package on most Linux distros, and the package name varies by distro. Replace example.com, the nameserver, and selector1 with your own values. The selector should come from the s= tag of a real outgoing message, not from memory.
BASH
# 1. Which nameservers is the domain actually delegated to?
dig +short NS example.com

# 2. Ask one of those authoritative nameservers directly (skips resolver caches)
dig @ns1.example.net +short TXT selector1._domainkey.example.com

# 3. Check whether the panel doubled the domain
dig @ns1.example.net +short TXT selector1._domainkey.example.com.example.com

# 4. If your email service uses CNAME-based DKIM, check the CNAME instead
dig @ns1.example.net +short CNAME selector1._domainkey.example.com
Start with the first query and compare it with the DNS provider whose panel you edited. If they don't match, you've been editing a zone nobody reads, and nothing else on this list matters until delegation is sorted out. For the second query, an empty result means the record isn't at the correct name. If the third query returns your key, you've found the doubled hostname. Delete the misplaced record and recreate it with only the relative part (selector1._domainkey), or whatever form your panel expects. When the second query does return something, read it closely. With +short, dig prints each TXT string in double quotes, with a space between strings. That space is only display formatting. The verifier joins the strings without it. A healthy 2048-bit record usually shows two or more quoted chunks, starting with v=DKIM1; and k=rsa;, then a p= value that continues across the chunks with no stray characters. Warning signs are a backslash-escaped quote inside the value, a key that ends abruptly, or a p= that's much shorter than the key you were given. Comparing the joined value character by character against the original key from your mail server is tedious, but it settles the question. Once DNS looks right, send a test message to a mailbox you control and read the headers. That's the only way to confirm the selector and key the server actually uses match what you published. The practical habit is simple: don't trust the panel's confirmation, trust the authoritative answer. Check delegation first, query the exact selector._domainkey name the signature points to, look for a doubled domain, and read the key strings before blaming the mail server. Most "DKIM is saved but failing" cases resolve somewhere in those four steps.