Docs / Email Servers / Troubleshooting DKIM Failures

Troubleshooting DKIM Failures

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 468 views · 5 min read

DomainKeys Identified Mail (DKIM) signs outgoing emails with a cryptographic signature, allowing receiving servers to verify the message was not altered in transit and originated from an authorized sender. DKIM failures cause emails to land in spam or get rejected entirely. This guide covers diagnosing and fixing the most common DKIM issues.

Understanding DKIM

DKIM works in three steps:

  1. Signing — your mail server signs outgoing messages by hashing specific headers and the body, then encrypting the hash with a private key
  2. DNS publication — the corresponding public key is published as a TXT record at selector._domainkey.domain.com
  3. Verification — receiving servers fetch the public key from DNS, decrypt the signature, and compare hashes

Diagnosing DKIM Failures

Check Email Headers

Look at the Authentication-Results header in received emails:

Authentication-Results: mx.google.com;
    dkim=fail (body hash did not verify) header.d=example.com header.s=mail;
    spf=pass smtp.mailfrom=example.com;
    dmarc=fail (p=QUARANTINE) header.from=example.com

Common DKIM result values:

  • dkim=pass — signature verified successfully
  • dkim=fail — signature verification failed
  • dkim=temperror — temporary DNS lookup failure
  • dkim=permerror — permanent error (missing key, invalid format)
  • dkim=neutral — message not signed or signature could not be evaluated

Verify DNS Record

# Check if DKIM record exists and is correct
dig TXT mail._domainkey.example.com +short

# Expected output (example):
# "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki..."

# Common issues:
# - No record found → record missing or wrong selector
# - Truncated key → DNS provider split the TXT record incorrectly
# - Multiple TXT records → conflicting entries

Test DKIM Online

# Use command-line tools
opendkim-testkey -d example.com -s mail -vvv

# Or online tools:
# - https://www.mail-tester.com (send email, get detailed report)
# - https://mxtoolbox.com/dkim.aspx
# - https://dkimvalidator.com

Common DKIM Failures and Fixes

1. "body hash did not verify"

The message body was modified after signing. Common causes:

  • Mailing lists — list software adds footers, modifying the body
  • Content filters — antivirus or DLP systems rewrite content
  • Email forwarding — forwarding services may modify the message
# Fix: Use relaxed canonicalization (tolerates minor modifications)
# OpenDKIM config:
Canonicalization    relaxed/relaxed

# Rspamd config (/etc/rspamd/local.d/dkim_signing.conf):
use_domain = "header";
allow_hdrfrom_mismatch = true;

2. "key not found in DNS"

The receiving server could not find the DKIM public key:

# Verify the selector matches between signing config and DNS
# Check your signing configuration for the selector name
grep -i selector /etc/opendkim.conf
# selector    mail

# Then verify DNS has a record at exactly: mail._domainkey.example.com
dig TXT mail._domainkey.example.com

# Common mistakes:
# - Wrong selector name in config vs DNS
# - Missing subdomain prefix (_domainkey)
# - DNS propagation not complete (wait 1-24 hours)
# - Record at wrong domain (using subdomain instead of main domain)

3. "key too short" or "insecure key"

# RSA keys shorter than 1024 bits are rejected by most providers
# Google requires minimum 1024-bit keys

# Generate a 2048-bit key (recommended):
opendkim-genkey -b 2048 -d example.com -s mail
# This creates mail.private (private key) and mail.txt (DNS record)

# Note: 2048-bit DKIM keys may need to be split across multiple DNS strings
# Most DNS providers handle this automatically

4. DNS TXT Record Truncation

# 2048-bit DKIM keys exceed the 255-character limit for a single DNS TXT string
# The key must be split into multiple strings within one TXT record

# Correct format (note the two quoted strings):
mail._domainkey    TXT    "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki...first255chars" "...remaining chars..."

# Some DNS providers handle splitting automatically
# If not, manually split the p= value at 255-character boundaries

# Verify the full key is retrievable:
dig TXT mail._domainkey.example.com +short | tr -d '" '

5. Multiple Signing Domains

# If your server handles multiple domains, each needs its own DKIM key

# OpenDKIM KeyTable (/etc/opendkim/KeyTable)
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
mail._domainkey.example.org example.org:mail:/etc/opendkim/keys/example.org/mail.private

# SigningTable (/etc/opendkim/SigningTable)
*@example.com mail._domainkey.example.com
*@example.org mail._domainkey.example.org

6. Signature Expired

# DKIM signatures can have an expiration time (x= tag)
# If the signature expires before delivery, verification fails

# Check if your signing config sets expiration:
# x= tag in the DKIM-Signature header indicates expiration
# Remove or increase the expiration time

# OpenDKIM: remove or increase SignatureExpiration
# SignatureExpiration  604800  # 7 days (or remove this line)

Testing Your DKIM Setup

# Send a test email and check the raw headers
echo "DKIM test" | mail -s "DKIM Test $(date)" check-auth@verifier.port25.com

# The auto-reply shows detailed DKIM verification results

# Or use swaks for detailed testing
swaks --to check@dkimvalidator.com \
    --from test@example.com \
    --server localhost \
    --header "Subject: DKIM Test"

DKIM Key Rotation

# Rotate DKIM keys periodically (every 6-12 months recommended)

# 1. Generate new key with a new selector
opendkim-genkey -b 2048 -d example.com -s mail202501

# 2. Add new DNS record
# mail202501._domainkey.example.com TXT "v=DKIM1; k=rsa; p=..."

# 3. Wait for DNS propagation (24-48 hours)

# 4. Update signing configuration to use new selector
# Selector    mail202501

# 5. Restart mail service
sudo systemctl restart opendkim postfix

# 6. After confirming new key works, remove old DNS record

Best Practices

  • Use 2048-bit RSA keys minimum (or Ed25519 where supported)
  • Use relaxed/relaxed canonicalization to handle minor message modifications
  • Test DKIM after any mail server configuration changes
  • Rotate DKIM keys every 6-12 months
  • Monitor DMARC aggregate reports for DKIM failure patterns
  • Sign with the header From domain, not the envelope sender domain
  • Combine DKIM with SPF and DMARC for comprehensive email authentication
  • Do not set overly short signature expiration times

Was this article helpful?