Introduction
DKIM (DomainKeys Identified Mail) signs outgoing emails with a private key and publishes the corresponding public key in DNS. Receiving mail servers verify the signature against the DNS public key. After rotating the DKIM key pair, if the DNS record still contains the old public key, all outgoing emails fail DKIM verification, damaging domain reputation and increasing the likelihood of emails being marked as spam.
Symptoms
- Email headers show
DKIM: failordkim=neutral (bad signature) - Google Postmaster Tools shows DKIM failure rate increasing
- DMARC reports show DKIM alignment failures
- Emails that previously passed DKIM now fail after key rotation
- Error message:
dkim=fail reason="signature verification failed"
Common Causes
- DNS TXT record for the DKIM selector not updated with the new public key
- New private key used for signing does not match the published public key
- DNS propagation delay after updating the DKIM record
- Multiple DKIM selectors and the wrong one is being used for signing
- DKIM key rotation process incomplete -- only the private key was changed
Step-by-Step Fix
- 1.Check the current DKIM DNS record: Verify the published public key.
- 2.```bash
- 3.# Check the DKIM selector record (e.g., default._domainkey)
- 4.dig TXT default._domainkey.example.com +short
- 5.# Should return: "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUA..."
- 6.
` - 7.Verify the signing key matches the DNS record: Compare the key pair.
- 8.```bash
- 9.# Check the private key on the mail server
- 10.openssl rsa -in /etc/opendkim/keys/example.com/default.private -pubout -outform PEM
- 11.# Compare the output with the public key in DNS
- 12.# They should be the same key pair
- 13.
` - 14.Update the DNS record with the new public key: Publish the correct key.
- 15.```dns
- 16.# Update the TXT record at your DNS provider:
- 17.# Name: default._domainkey
- 18.# Type: TXT
- 19.# Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
- 20.# TTL: 3600 (lower TTL during rotation)
- 21.
` - 22.Wait for DNS propagation and test DKIM verification: Confirm the fix works.
- 23.```bash
- 24.# Wait for DNS propagation
- 25.dig TXT default._domainkey.example.com @8.8.8.8 +short
- 26.# Send a test email and check headers
- 27.# Send to check-auth@verifier.port25.com for automated DKIM check
- 28.
` - 29.Implement overlapping key rotation for future rotations: Avoid verification gaps.
- 30.
` - 31.# Best practice for DKIM key rotation:
- 32.# 1. Generate new key pair
- 33.# 2. Publish new public key with a new selector (e.g., default2._domainkey)
- 34.# 3. Switch signing to the new private key
- 35.# 4. Wait 48 hours for old emails to be delivered
- 36.# 5. Remove the old public key from DNS
- 37.
`
Prevention
- Use a documented DKIM key rotation procedure that includes DNS update steps
- Keep the old DKIM selector in DNS for at least 48 hours after rotation
- Monitor DKIM pass rates and alert on sudden drops after key changes
- Use lower TTL (300s) for DKIM records during rotation periods
- Automate DKIM key rotation with DNS API integration
- Test DKIM verification in staging before applying key rotation to production