DKIM Signature Verification Failures

Intermediate Email Deliverability

Receiving mail servers are rejecting or flagging your outbound email with `dkim=fail` in the Authentication-Results header, meaning the cryptographic signature attached to the message does not match the public key published in your DNS. This typically causes DMARC to fail, pushing messages to spam or triggering outright rejection depending on your policy.

Symptoms

  • Authentication-Results header shows `dkim=fail (bad signature)` or `dkim=permerror`
  • DMARC reports list high counts of dkim=fail for your domain's messages
  • Emails pass SPF but still land in spam due to combined DMARC failure
  • Transactional emails from a specific sending service suddenly begin failing
  • dig query for your DKIM selector returns no record or an unexpected key
  • DKIM check at mail-tester.com reports 'Invalid DKIM signature'

Possible Root Causes

  • DNS TXT record for the DKIM selector was deleted, expired, or never published
  • Selector name in the outbound signature does not match the name in the DNS record
  • A relay or mailing list manager appended a disclaimer or modified headers/body after signing
  • Private key was rotated on the sending server but the old public key was removed from DNS before the TTL expired
  • Key length is too short (512-bit keys rejected by modern validators) or the algorithm is unsupported

Diagnosis Steps

Step 1: Identify the DKIM Selector in Use

Examine full message headers of a failing email. Find the DKIM-Signature header:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
  s=mail2024; h=from:to:subject:date:message-id; bh=...; b=...

The s= value is your selector (here: mail2024) and d= is the signing domain.

Step 2: Query the Published Public Key

# Format: <selector>._domainkey.<domain>
dig TXT mail2024._domainkey.example.com +short

# Expected output (truncated):
# "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

# If the record is missing:
dig TXT mail2024._domainkey.example.com
# Returns NXDOMAIN or SERVFAIL

Step 3: Test DKIM Validation Manually

Send a test email to [email protected] and review the full report, or use:

# Using opendkim-testkey (requires opendkim-tools)
opendkim-testkey -d example.com -s mail2024 -vvv

Step 4: Identify the Failure Mode

Error Likely Cause
dkim=fail (bad signature) Message body or headers were modified in transit
dkim=permerror (no key for signature) DNS record missing or selector name mismatch
dkim=temperror Transient DNS lookup failure
dkim=fail (public key: not available) Key was rotated and old selector removed prematurely

Step 5: Detect In-Transit Modification

If the key is present but the signature fails, a relay or mailing list is likely modifying the message:

# Check Received headers to trace the relay chain
# Look for systems inserting headers (disclaimers, footers, X-* headers)

Solution

Republish or Correct the DNS Record

Retrieve the correct public key from your ESP or mail server, then publish the TXT record:

# DNS TXT record name:
mail2024._domainkey.example.com

# DNS TXT record value:
v=DKIM1; k=rsa; p=<base64-public-key>

Wait for the TTL to expire (check current TTL with dig TXT mail2024._domainkey.example.com and look at the TTL field), then retest.

Fix Selector Mismatch

Ensure your mail server or ESP is signing with the selector whose public key is published:

# Postfix with OpenDKIM — check /etc/opendkim/signing.table
# Example entry: *@example.com  mail2024._domainkey.example.com

# Restart OpenDKIM after changes
sudo systemctl restart opendkim
sudo systemctl restart postfix

Handle In-Transit Modification

  • Use c=relaxed/relaxed canonicalization (allows minor whitespace changes)
  • If a mailing list is the culprit, configure ARC (Authenticated Received Chain) sealing on the list server
  • Move disclaimers to the MIME boundary rather than appending raw text after the signature

Key Rotation Best Practice

When rotating keys, keep the old selector active in DNS for at least 72 hours (one TTL cycle) after switching the signing selector:

# Old selector: mail2023._domainkey.example.com  → keep alive
# New selector: mail2024._domainkey.example.com  → activate signing
# After 72h: remove mail2023 record

Prevention

  • Use 2048-bit RSA keys or Ed25519; avoid 512-bit and 1024-bit keys which are being rejected by major providers
  • Set DNS TTL on DKIM records to 3600 seconds (1 hour) to allow faster rollover without stale-cache failures
  • Monitor DMARC aggregate reports weekly to catch dkim=fail spikes early
  • Test DKIM after every ESP reconfiguration or DNS change using mail-tester.com or dkimvalidator.com
  • Document all active selectors and their intended expiry dates in your DNS runbook

Related Protocols

Related Terms

More in Email Deliverability