DKIM Signature Verification Failures
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://ipfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://ipfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://ipfyi.com/entity//)
Use the native HTML custom element.
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/relaxedcanonicalization (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