SPF authorises servers, DKIM authenticates messages. How the signing and verification cycle works, what each tag in the header does, and where signatures break.
Our SPF walkthrough covered the mechanism that authorises which servers may send for your domain. SPF asks a question about the connecting IP and the envelope sender, and it says nothing whatsoever about the message that arrives. DKIM answers the other half. It attaches a cryptographic signature to the message itself, so a receiver can verify that the signed headers and the body were not altered in transit, and that whoever signed controls a key published in your DNS. The two protocols are complementary rather than redundant, which is why DMARC accepts a pass from either one, and why senders running SPF alone watch authentication collapse the moment a message is forwarded.
What the signature actually covers
Signing happens on the outbound path, after the message is composed and before it leaves your infrastructure. The signer picks a set of headers, computes a hash of the body, computes a second hash over those chosen headers, and encrypts the result with a private key that never leaves the sending system. The output is one DKIM-Signature header prepended to the message. Nothing is concealed: the signature proves integrity and origin, not confidentiality, and a recipient whose client ignores DKIM entirely still reads the mail normally. The verifier reverses the process by fetching the matching public key from DNS, recomputing both hashes, and comparing.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=s2023a; t=1679400000;
h=from:to:subject:date:message-id;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzRThe tags that decide the outcome
Four tags carry most of the operational weight. d= names the signing domain, and it is the value DMARC compares against the From header, so an ESP that signs with its own domain gives you a perfectly valid signature that proves something about the provider. s= is the selector, a label pointing at one specific key, which allows several keys to coexist so rotation is a switch rather than a race. h= lists the headers under signature, and any header absent from that list can be modified in transit without breaking anything. bh= is the body hash, which is why appending a footer to a signed message invalidates it. The rest are situational: canonicalization, timestamps, and expiry.
Why signatures fail in production
The five failures worth checking first
- 1
The key is not published, or not propagated
The selector named in the header must resolve. A rotation applied at the MTA before DNS caught up produces a clean-looking header and a hard verification failure.
- 2
The TXT record is truncated
A 2048-bit key has to be split across multiple quoted strings inside one record. DNS providers that silently truncate instead of splitting are a common cause of permanent failure.
- 3
The message was modified after signing
Security gateways, list servers, and marketing platforms that rewrite subjects or inject footers change bytes the signature covers. The body hash fails first.
- 4
The signature uses the provider's domain
A default ESP configuration signs with its own domain. The signature verifies and buys you nothing under DMARC, because the signing domain does not match your From header.
- 5
The key is weak or stale
1024-bit keys are treated with suspicion and discounted by some receivers. 2048 bits is the working default, with rotation on a documented schedule.
Verification is cheap to test and expensive to assume. Send a message to a mailbox you control at a provider that reports results, read the Authentication-Results header, and confirm that the domain shown in header.d is the domain in your From address rather than your provider's. That single check catches the failure mode that costs senders the most, which is a signature that passes on its own terms while proving something about somebody else's domain.
Frequently Asked Questions
Does DKIM stop anyone from spoofing my domain?
How many selectors should I publish?
Should the private key ever leave the sending system?
Does a longer key improve deliverability?
Key Takeaways
- DKIM signs the message, SPF authorises the server, and DMARC accepts a pass from either, so run both
- The d= tag is what DMARC compares against your From domain, and provider-domain signing quietly fails that test
- The h= list defines what is protected, and anything outside it can be rewritten in transit undetected
- Skip the l= tag entirely, publish 2048-bit keys, and split long TXT records correctly
- Verify by reading Authentication-Results on a real delivery, not by trusting a sending platform dashboard
Related articles

DMARCbis Is Published: What RFC 9989 Changes
After eleven years, DMARC is a real standard: RFC 9989, 9990, and 9991 replace RFC 7489. What is different, what stays, and the short list of actions for senders.

Subaddressing: What Plus Addresses Tell Senders
user+anything@gmail.com is one mailbox wearing labels. How subaddressing works, why blocking it backfires, and what plus addresses reveal about your data flows.

DNSSEC for Email Operators: Worth It, and How Not to Break Everything
Every email trust decision resolves through DNS, and DNSSEC is what makes those answers tamper-proof. What it buys email, what DANE requires, and safe operations.


