Skip to main content
All fixes

Email deliverability, DNS, SPF/DKIM/DMARC

Fix Invalid DKIM Key in DNS TXT Record

Truncated, malformed, or mismatched DKIM keys produce dkim=permfail at every receiver. Republish the public key exactly as the ESP supplies it.

What's happening

An invalid DKIM key surfaces as dkim=permfail in receiver headers — the receiver retrieved the TXT record but could not parse the public key, the key did not match the signing private key, or the record violated RFC 6376 syntax. Unlike a missing record (dkim=none), permfail is a hard failure that DMARC counts against you.

Three categories of invalidity dominate. First, truncation: many DNS UIs cap TXT values at 255 characters and silently chop the base64 public key. Second, format error: missing v=DKIM1 prefix, missing semicolons, or bad base64 padding. Third, mismatch: the published public key does not correspond to the private key the ESP is using to sign — this happens when keys are rotated at the ESP but DNS is not updated.

The receiver-side outcome is equivalent to having no DKIM at all, plus the additional reputation penalty that comes with explicit authentication failure. DMARC enforcement makes this much worse than dkim=none because permfail is treated as a disqualifying signal.

Why it matters

Gmail's bulk-sender enforcement rejects messages with dkim=permfail when DMARC is also failing. Microsoft 365 routes mail to junk with high SCL scores and the X-Microsoft-Antispam header marks it CAT:DKMI.

Domain reputation drops within hours of high-volume sending under permfail conditions. Recovery requires not only fixing the key but also a multi-week reputation rebuild via gradual volume ramp-up.

Mailing-list and forwarded mail is permanently broken — without a valid DKIM signature, the only authentication that survives forwarding is gone, and all forwarded messages bounce or junk.

Common causes

  • DNS provider truncated the long base64 key value to 255 characters.
  • Operator pasted the key with line breaks or whitespace inside the base64 string.
  • Private/public key pair mismatch after ESP key rotation that did not update DNS.
  • Wrong key algorithm marker (k=rsa missing or set to k=ed25519 without ESP support).
  • Trailing zeros or smart quotes from copy-pasting.
  • Subdomain-vs-apex confusion (selector record published at wrong name).

Detect this on your site

Run a quick scan with the Email Checker. The tool surfaces this exact issue with the records and context needed to apply the fix below.

Open Email Checker

How to fix it

  1. 1

    Identify the failing selector

    Open a recent message in Gmail's Show Original or your bounce log. Read the DKIM-Signature header and note the s= (selector) and d= (domain) values. The published TXT record at._domainkey. is the one to verify.

  2. 2

    Pull the record and inspect length

    Run dig +short TXT s=selector._domainkey.example.com (substitute your selector). Count the base64 characters in the p= field. A 2048-bit RSA key has approximately 392 base64 characters; if you see 200 or fewer, the value is truncated.

  3. 3

    Re-copy the key from the ESP exactly

    Open the ESP dashboard's domain authentication page and click "copy DNS records". Paste into a plain text file (no rich-text editors). Compare the new value to your published value character by character — even one missing character invalidates the entire key.

  4. 4

    Republish using a provider that supports long TXT

    Cloudflare DNS, Route 53, and Google Cloud DNS handle long TXT records natively. If your provider truncates, either switch DNS providers or split the value into multiple quoted character-strings on a single record (Cloudflare: paste the full string and it auto-chunks; Route 53: enclose each 255-char chunk in its own pair of double quotes).

  5. 5

    Confirm via the ESP's verify button

    After republishing, return to the ESP and click "Verify" on the domain. The ESP runs an internal check that signs a probe message and resolves the TXT record — verification passing confirms the public key matches the signing private key.

  6. 6

    Send a Mail-Tester probe and check headers

    Send a fresh test through your production sending path to a mail-tester.com address. The DKIM row should read "DKIM signature is valid" with the correct selector. In Gmail, Show Original should show dkim=pass header.d=example.com.

Example

; Wrong — truncated to 255 chars, key fragment
sg1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1vR7CxKj..."

; Right — Route 53 syntax with multiple chunks on one record
sg1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1vR7CxKjZ...first255chars" "...next255chars...QIDAQAB"

Long DKIM keys must be chunked into multiple quoted strings if the DNS UI does not auto-chunk.

Frequently asked

permfail and fail are functionally equivalent in modern receivers — both mean cryptographic verification could not succeed. RFC 6376 distinguishes them: permfail means a permanent error in retrieval or parsing fail means signature verification failed. Either way the message is treated as unauthenticated.

No one selector can only hold one public key. To rotate without downtime publish a new selector (e.g. sg2._domainkey) wait for propagation switch the ESP to sign with the new selector then delete the old selector record after a few days.

Recommended but not required. DNSSEC protects against active DNS-spoofing attacks where an attacker injects a forged public key. Most production deployments enable DNSSEC for the entire zone which covers DKIM by default.

Related fixes