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: fail or dkim=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. 1.Check the current DKIM DNS record: Verify the published public key.
  2. 2.```bash
  3. 3.# Check the DKIM selector record (e.g., default._domainkey)
  4. 4.dig TXT default._domainkey.example.com +short
  5. 5.# Should return: "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUA..."
  6. 6.`
  7. 7.Verify the signing key matches the DNS record: Compare the key pair.
  8. 8.```bash
  9. 9.# Check the private key on the mail server
  10. 10.openssl rsa -in /etc/opendkim/keys/example.com/default.private -pubout -outform PEM
  11. 11.# Compare the output with the public key in DNS
  12. 12.# They should be the same key pair
  13. 13.`
  14. 14.Update the DNS record with the new public key: Publish the correct key.
  15. 15.```dns
  16. 16.# Update the TXT record at your DNS provider:
  17. 17.# Name: default._domainkey
  18. 18.# Type: TXT
  19. 19.# Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
  20. 20.# TTL: 3600 (lower TTL during rotation)
  21. 21.`
  22. 22.Wait for DNS propagation and test DKIM verification: Confirm the fix works.
  23. 23.```bash
  24. 24.# Wait for DNS propagation
  25. 25.dig TXT default._domainkey.example.com @8.8.8.8 +short
  26. 26.# Send a test email and check headers
  27. 27.# Send to check-auth@verifier.port25.com for automated DKIM check
  28. 28.`
  29. 29.Implement overlapping key rotation for future rotations: Avoid verification gaps.
  30. 30.`
  31. 31.# Best practice for DKIM key rotation:
  32. 32.# 1. Generate new key pair
  33. 33.# 2. Publish new public key with a new selector (e.g., default2._domainkey)
  34. 34.# 3. Switch signing to the new private key
  35. 35.# 4. Wait 48 hours for old emails to be delivered
  36. 36.# 5. Remove the old public key from DNS
  37. 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