What Is DKIM? A Complete Guide to Email Signing
DKIM (DomainKeys Identified Mail) is an email authentication standard that uses public-key cryptography to sign outgoing messages, letting receiving servers verify the email wasn't tampered with and actually came from the sender's domain.
DKIM (DomainKeys Identified Mail) is an email authentication protocol that uses public-key cryptography to sign outgoing messages. Receiving servers verify that signature against a public key published in your DNS, confirming the email came from your domain and wasn't altered in transit. It's defined in RFC 6376.
Google reported that requiring authentication on bulk senders in early 2024 cut unauthenticated traffic to Gmail users by 65% within months (Google Security Blog, 2024). DKIM sits at the center of that shift; if your mail isn't signed, large mailbox providers now assume it's suspicious by default.
What is DKIM?
DKIM is a cryptographic signature attached to every email you send. The sending server signs a chosen set of headers plus the body with a private key; the receiving server fetches the matching public key from your DNS, recomputes the hash, and checks that the two match. If they agree, the message is authentic.
The spec has been stable since 2011, when RFC 6376 superseded the original RFC 4871. It works alongside SPF and DMARC, but it answers a different question. SPF asks whether a given IP is allowed to send for your domain; DKIM asks whether the claimed domain actually signed this exact message. That distinction has a practical consequence: SPF breaks the moment mail gets forwarded, whereas a DKIM signature survives most forwarding paths unless a mailing list rewrites the body.
Think of it as a wax seal on a letter. Anyone can copy the envelope; forging the seal requires the private key sitting on your mail server.
How DKIM works
Signing and verifying a message takes roughly 20 milliseconds end to end. When you send an email, your mail server (or your ESP, if you use one) does four things:
- Picks a canonicalized version of the headers and body.
- Runs that content through a hash function, usually SHA-256.
- Encrypts the hash with the private key tied to a specific selector.
- Attaches the result as a
DKIM-Signature:header on the outbound message.
The receiving server does the reverse. It reads the DKIM-Signature header, notes the domain (d= tag) and selector (s= tag), looks up <selector>._domainkey.<domain> in DNS, pulls down the public key, decrypts the signature, and compares hashes. Match is a pass, mismatch is a fail, and a missing key is a permfail.
A selector is just a label. It lets you publish several DKIM keys for one domain, which matters as soon as you send through more than one provider: your ESP, your transactional service, your help desk, your payroll system. Each gets its own selector and its own public key, and they never collide. A typical selector looks like google2048, mailneo202604, or just s1.
Gmail's sender guidelines require DKIM signing for any sender pushing more than 5,000 messages per day to personal Gmail accounts; Yahoo adopted the same bar in February 2024. That isn't advice anymore, it's enforced at the SMTP layer.
What a DKIM record looks like
A DKIM public-key record is a TXT record in DNS:
Host: mailneo202604._domainkey.example.com
Type: TXT
Value:
v=DKIM1;
k=rsa;
p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtvX9kP2yT8k...
[base64 public key continues here, typically 400+ characters for 2048-bit]
...nQIDAQAB
The tags break down as follows:
| Tag | Required? | What it means |
|---|---|---|
v=DKIM1 | Required | Version, always this exact value. |
k=rsa | Optional | Key type. RSA is the default; Ed25519 is defined but barely supported in the wild. |
p=... | Required | The base64-encoded public key itself. An empty p= revokes the key. |
t=y | Optional | Test mode. Remove it once signing is verified; some receivers ignore signatures while it's set. |
s=email | Optional | Service type. Leave it out unless you have a specific reason. |
The email you send carries a matching DKIM-Signature header:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=mailneo202604;
h=from:to:subject:date:message-id;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=K9x3n...signature...Ql==
The h= tag lists which headers got signed; bh= is the body hash; b= is the signature itself. To see yours, send a test to a mailbox you control and view the raw source in Gmail via "Show original", or use the DKIM generator to produce a key pair and the DNS record in one shot.
The c= tag tells the receiver how to clean up whitespace and capitalization before hashing. There are two choices: simple (exact match, zero tolerance) and relaxed (collapse extra whitespace, lowercase header names). Use relaxed/relaxed. Simple canonicalization breaks if any intermediate server adds a space or rewraps a line, which happens constantly. I've seen one legitimate reason to use simple in five years, and it was a forensic investigation.
Why DKIM decides your deliverability
DKIM is a prerequisite for DMARC, which is the policy layer that tells mailbox providers what to do with unauthenticated mail. No DKIM means no durable DMARC pass on forwarded messages, which means fragile delivery the minute your email hits a mailing list or a corporate gateway.
Two effects you'll feel directly. Without DKIM alignment, DMARC can't pass when SPF breaks; your aggregate reports will show policy failures on legitimate mail that simply got forwarded. And both Microsoft and Google feed DKIM signals into reputation scoring, so a consistently signed domain builds sender reputation faster than an unsigned one. Reputation is what decides inbox versus promotions versus spam, and it's why inbox placement rate is a more honest health metric than open rate.
Authentication is table stakes rather than an optimization; the rest of the picture is list quality, cadence, and complaints. Google's bulk sender rules cap the spam complaint rate at 0.3%, and no amount of correct DNS will rescue a list that trips it. The email deliverability guide covers that wider stack.
Setting up DKIM correctly
Rough order of operations, assuming you send through an ESP:
- Generate a 2048-bit RSA key pair. RFC 8301 deprecated 1024-bit keys in 2018. Some DNS providers still choke on the longer record and need the value split into two quoted strings; that's fine, receivers concatenate them.
- Pick a selector name with a date or version in it, like
s202604. You'll thank yourself during rotation. - Publish the public key as a TXT record at
<selector>._domainkey.<yourdomain.com>. Propagation usually takes under an hour; give it up to 24. - Store the private key on the sending server or in your ESP's config. Never commit it to git, never email it to yourself.
- Send a test message to a mailbox you control, view the raw headers, and look for
dkim=passin theAuthentication-Resultsblock. - Check alignment. The domain in
From:has to match, or be a subdomain of, thed=tag for DMARC to treat DKIM as aligned.
On alignment, DMARC offers two modes. Relaxed is the default and lets a subdomain match its parent, so signing with d=mail.example.com aligns with From: sales@example.com. Strict demands an exact match and will fail that same pair. Unless you work somewhere regulated enough to want tighter scoping, leave it relaxed; cross-subdomain sending then works without odd failures.
If you're on Mailneo, the DKIM record appears in your domain settings the moment you add a sending domain. Copy it into your DNS, click verify, and we report pass or fail. The setup guide for SPF, DKIM, and DMARC together covers the full workflow, SPF vs. DKIM vs. DMARC explains how the three interact, and there are deeper pieces on what is SPF and what is DMARC.
Rotating keys, and the mistakes that break signatures
Keys should rotate. DKIM.org's operator recommendations suggest rotating at least every six months; quarterly is better at high volume. The reasoning is unglamorous: old keys sit in zone-transfer history, on backup media, in cached DNS records, and a compromise you don't know about gets more likely the longer a key lives.
Rotation means publishing a new selector, pointing the signing config at it, keeping the old selector live for a few days so in-flight mail still verifies, then revoking the old public key by replacing its p= value with an empty string.
The failures I see over and over:
- Publishing the private key instead of the public one. It sounds absurd; it happens every month. The
p=value is the public half of the pair. - Sticking with 1024-bit keys because "the DNS provider doesn't support longer TXT values." All the major providers do now, usually by splitting into multiple quoted strings. If yours doesn't, change providers or use a CNAME-based ESP setup.
- Corrupting the base64 value on paste, or dropping the trailing
==. One missing character breaks every signature you send. - Signing too few headers. The
h=tag should cover at leastFrom,To,Subject,Date, andMessage-ID. Signing onlyFrom:is technically valid and trivially bypassable.
Encryption and failure modes
Two things the spec does not make obvious, and both come up constantly in support tickets.
Does DKIM encrypt my email?
No. DKIM signs; it does not conceal. The contents stay readable by every server that handles the message. For protection in transit you need TLS, which most providers negotiate automatically; for end-to-end secrecy you need S/MIME or PGP. The email authentication glossary entry lays out how these pieces relate.
What happens when a DKIM signature fails?
It depends on your DMARC policy. At p=none, a failed DKIM check usually doesn't block delivery on its own, since SPF may still pass. At p=quarantine or p=reject, a DKIM failure with no aligned SPF sends the message to spam or bounces it outright. The DKIM glossary entry has the full interaction chart.
Explore: Email Deliverability
Related Articles
SPF, DKIM, and DMARC for Developers Who Just Want Their App's Email to Land in the Inbox
A practical, opinionated walkthrough of the three DNS records your app needs to send transactional or product email that doesn't land in spam. Written for developers who would rather ship than read RFCs.
What Is SPF? How Sender Policy Framework Protects Your Email
SPF (Sender Policy Framework) is a DNS-based email authentication protocol that lets domain owners publish a list of IP addresses allowed to send mail on their behalf. Receivers check the list; unauthorized senders get rejected or flagged. It's one of three core standards (with DKIM and DMARC) that keep spoofed mail out of inboxes.
Understanding Email Headers: A Technical Guide
Email headers are the metadata that rides along with every message; they tell you where a mail came from, every server it touched, whether SPF, DKIM, and DMARC passed, and why a message got delayed, bounced, or flagged as spam.
What Is DMARC? How to Protect Your Domain from Spoofing
DMARC is a DNS-based email authentication policy that tells receivers what to do when a message fails SPF or DKIM checks. It requires at least one of those two protocols to work, and publishes a policy (none, quarantine, or reject) at _dmarc.yourdomain.com.
Ready to supercharge your email marketing?
Start sending smarter emails with AI-powered campaigns. No credit card required.
Get Started Free