DKIM means the sending server or service signs each message with a private key, and the receiver checks that signature against a public key published in DNS. The signature travels in a DKIM-Signature header, and the signing domain (d=) and selector (s=) tell the receiver where to find the key. A valid signature shows that the signed content was not altered after signing. It does not, on its own, show that the signing domain is the domain in the visible From line. For publishers and shop owners who send newsletters or order emails, the practical job is to make every sending system sign under your own domain and to keep the keys tidy.
Who may be emailed in the first place is a consent question and a separate subject; our piece on consent-based newsletter signups covers it. The sections below follow the signature from what it proves to how it breaks.
What a valid signature proves and what it does not
DKIM is specified in RFC 6376 (Opens in a new tab). It is easy to read "DKIM pass" as "this email is really from the sender shown". The RFC is more careful than that, and the difference matters for how you set up your own mail.
The narrow claim
Section 1.5 describes what a valid signature establishes: the hashed content has not changed since it was signed, and it asserts nothing else about end-to-end integrity. Section 1.2 adds that the signing identity does not have to match any address in a particular header field, and section 3.11 leaves it to the party assessing the message to decide whether d= and i= relate to other identities. The RFC does not require the signing domain to equal the From domain.
Where the link to From comes from
That link is made by DMARC. Under RFC 7489 (Opens in a new tab) section 3.1, a message passes DMARC when at least one mechanism produces a pass for an identifier aligned with the From domain, and with several DKIM signatures one aligned, verified signature is enough. Google's email sender guidelines (Opens in a new tab) say the same thing in plain terms: for direct email, the From: domain must align with the SPF domain or the DKIM domain. The same page asks everyone who sends to personal Gmail accounts to set up SPF or DKIM, and senders of 5,000 or more messages per day to set up both. Google's thresholds and wording can change, so read the current page before you act on them.
A valid signature is not a good reputation
Section 8.6 of the RFC describes a replay situation: a spammer sends spam through an MTA that signs it, and the signed copy can then be reused. The signature stays valid because the content has not changed. DKIM is evidence of identity and integrity, not of good behavior. That is also why the Gmail page lists spam rate and user complaints as separate factors from authentication.
Anatomy of the DKIM-Signature header
A sending system builds the header by hashing selected headers and the body, signing the result with the private key, and adding the DKIM-Signature field to the message. A receiver reverses the steps with the public key.
The tags a site owner should recognize
| Tag | Meaning | Detail from RFC 6376 section 3.5 |
|---|---|---|
| v= | Version | Must be 1 |
| a= | Algorithm | Signers should use rsa-sha256 (also section 3.3) |
| d= | Signing domain (SDID) | Must correspond to a DNS name under which the key record is published |
| s= | Selector | Required |
| h= | Signed header names | From must be included (section 5.4) |
| bh= | Body hash | Hash of the canonicalized body |
| b= | Signature data | Treated as empty while the signature is computed |
| c= | Canonicalization | Defaults to simple/simple |
| t=, x= | Timestamp, expiration | Both recommended; x= is not intended as an anti-replay defense |
| i= | Agent or user identity | Optional; its domain must be the same as or a subdomain of d= |
| z= | Copied header fields | For diagnostics only |
Canonicalization in one paragraph
Mail is sometimes reformatted slightly in transit, so both sides normalize the message before hashing. For headers, the simple method leaves fields untouched, while relaxed lowercases names, collapses runs of whitespace and trims whitespace before the colon and at the end (sections 3.4.1 and 3.4.2). For the body, simple removes trailing empty lines, and relaxed also reduces whitespace within and at the end of lines (sections 3.4.3 and 3.4.4). A sending service picks the method; if you read c=relaxed/relaxed in a header, nothing is wrong.
Which headers get signed
The h= tag lists the signed header names. Section 5.4 requires the From header to be among them, and section 6.1.1 says a verifier must treat a signature whose h= omits From as failed. The tag may also list header names that do not exist when signing, so a header added later can be detected (section 3.5). A header outside the list can change without breaking the signature, which is why knowing the list matters. Read h= in a raw message to see whether Subject, To and Date are covered.
The body length tag
The l= tag limits how much of the body is signed, and the RFC treats its misuse in section 8.2. Practical suggestion: if you operate your own signer, do not use l= without a clear reason, because content after the limit falls outside the signature.
Selectors and the public key record
A selector lets one domain hold several keys at once. Section 3.1 explains that selectors partition a domain's key namespace so multiple keys can be active, and that periods in a selector act as DNS label separators.
Where the key lives
Keys are stored in TXT records under a _domainkey subdomain. Section 3.6.2.1 gives an example: for d=example.com and s=foo.bar, the query goes to foo.bar._domainkey.example.com. The general pattern is selector, then "._domainkey.", then the domain. There must be one TXT record per selector, and when a record is written as several strings, they are joined without whitespace (section 3.6.2.2).
Tags in the key record
| Tag | Meaning | Detail |
|---|---|---|
| v= | Record version | If present, DKIM1 and the first tag |
| k= | Key type | Defaults to rsa |
| p= | Public key, base64 | An empty value means the key has been revoked |
| h= | Acceptable hash algorithms | Default allows all |
| s= | Service types | Default is *; email is the defined type |
| t= | Flags | y marks testing mode; s restricts the identity domain to match exactly |
| n= | Notes | For administrators, not end users |
On the testing flag the RFC is blunt: a verifier must not treat mail from a domain in testing mode differently from unsigned mail (section 3.6.1). The flag does not shelter a bad key. Practical suggestion: test a new selector with your own messages first and leave t=y out of the published record.
Key length without the math
Section 3.3.3 says signers must use keys of at least 1024 bits for long-lived keys, and that verifiers must handle keys from 512 to 2048 bits. The Gmail page says sending to personal Gmail accounts requires a key of 1024 bits or longer and recommends 2048 bits if your domain provider supports it. For a site owner the decision is simple: choose 2048 if the provider offers it. A 2048-bit public key is a long text value, and some DNS panels reject long values; look for an option to split the value into quoted strings.
Records handed to you by a sending service
When a service signs for you, it keeps the private key and gives you a name and a value to publish. Confirm the record type and name in the service's documentation; the RFC defines the TXT form only. Whether a service asks for other kinds of records is specific to that product, so follow its documentation.
Valid signature, no alignment
An authentication report can show DKIM pass while DMARC still fails. The signature is valid, but the d= domain is not the From domain.
How it happens
A sending tool signs with its own domain until you finish a domain setup. The signature verifies against the tool's key, which is exactly what DKIM promises, yet it says nothing about your From domain. The remedy is inside the tool: verify your domain and publish the records it gives you, after which messages are signed with your domain as d=. A tool may also add two signatures, one for itself and one for you, and under RFC 7489 an aligned one is enough.
Relaxed and strict alignment
Relaxed mode compares organizational domains, strict mode needs an exact match (RFC 7489 sections 3.1.1 and 3.1.2), and the adkim tag defaults to relaxed (section 6.3). If your DMARC record asks for strict DKIM alignment, d= must equal the From domain exactly.
Example scenario: a ceramics shop
Example scenario: A small ceramics shop sends order confirmations from its shop platform and a monthly studio newsletter from a separate tool. The raw header of the newsletter shows DKIM pass, but d= names the tool, not the shop. The owner verifies the shop's domain inside the tool, publishes the key record it provides, sends a test message to herself and confirms that d= now shows the shop's own domain. For the order confirmations she asks the platform whether it can sign under the shop's domain; until it can, that stream depends on SPF for alignment.
Alignment checklist
- Is d= in the raw header your domain, or the tool's?
- Does the tool add more than one signature? Which one carries your domain?
- Are d= and From under the same organizational domain?
- If DMARC asks for strict alignment, do d= and From match exactly?
Setting up DKIM with a sending service
Each service has its own panel, and the menu names in a localized interface may differ from the English labels in a service's documentation. The order below holds across services.
- Find the domain or sender authentication section in the service and add your domain.
- Copy the DNS record or records it gives you exactly: name, type and value. Check whether your DNS panel appends your domain to the name automatically, so it does not appear twice.
- Publish the records and allow time for DNS to update. Neither RFC 6376 nor the Gmail page gives a propagation time, because it depends on your DNS provider and the record's TTL.
- Press the verify button in the service.
- Send a test message to yourself and confirm that the DKIM-Signature header shows your domain in d=.
- Repeat for every other system that sends with your domain.
Setup check at a glance
| Check | Expected | If not |
|---|---|---|
| Selector record in DNS | One TXT record with a filled p= value | Copy name and value again |
| d= in the test message | Your domain | Finish domain verification in the service |
| s= in the test message | The selector the service named | Compare with the service documentation |
| From in the h= list | Present | Contact the service |
| Key length | At least 1024 bits, 2048 if offered | Ask for a longer key option |
Rotating keys and changing sending services
Selectors exist so that keys can change without a gap. Done in the wrong order, rotation breaks verification for a while.
A gap-free sequence
- Choose a new selector for the new key and publish its public key. Leave the old selector and key in place.
- After DNS has updated, switch the sending system to sign with the new private key and selector.
- Messages signed with the old selector may still be in transit, so keep the old public key published long enough for verification. The RFC gives no number of days.
- Then remove the old record or revoke it by emptying p=.
Sections 3.1 and 5.2 describe this use of selectors, and section 3.1 advises against reusing a selector for a new key, because forged mail then becomes harder to tell apart from mail signed with a key that is no longer valid.
Revocation
An empty p= revokes the key while keeping the selector known (section 3.6.1), and a verifier treats a signature that relies on a revoked key as failed (section 6.1.2). The RFC also notes that a domain's ability to revoke can be limited (section 8.7). If you suspect a private key leaked, deleting the old record is not enough; move to a new selector and stop the sender from using the old key.
Changing a sending service
| Step | New service | Old service |
|---|---|---|
| 1 | Publish its DKIM records | Leave alone |
| 2 | Confirm d= and s= in test messages | Keeps sending |
| 3 | Start sending | Stop sending |
| 4 | Monitor | Keep its key record for a while |
| 5 | Normal operation | Remove or revoke its key record |
Decision rule: new key or new selector
- Never write a new key under an old selector; every new key gets a new selector.
- When changing services, use the selector the service tells you to use.
- Before deleting an old selector, make sure nothing signs with it any more.
This rule is a practical suggestion drawn from the RFC's advice on selectors.
Reading failures
Section 6.1 of the RFC defines how a verifier handles signatures. When processing ends in PERMFAIL or TEMPFAIL, the verifier must stop processing that signature and may move to the next one.
Outcomes and likely causes
| Situation | RFC outcome | Likely cause |
|---|---|---|
| No key found | PERMFAIL, no key for signature (6.1.2) | Misspelled selector or domain, record not published |
| Key temporarily unavailable | TEMPFAIL, key unavailable (6.1.2) | Transient DNS problem |
| Body hash mismatch | PERMFAIL, body hash did not verify (6.1.3) | Body changed after signing |
| Signature mismatch | PERMFAIL, signature did not verify (6.1.3) | Header changed or key does not match |
| From not signed | PERMFAIL, From field not signed (6.1.1) | From missing from h= |
| Revoked key | Failed signature check (6.1.2) | p= emptied |
A temporary failure can clear without any change on your side, while a permanent failure means a record, selector or signature needs fixing. Before you conclude anything from one failed test, send the message again a few minutes later.
Diagnosis in five moves
- Send a test message and open the raw headers. Note d= and s= in the DKIM-Signature line.
- Build the key name: s value, then "._domainkey.", then d value. Query that name's TXT record with a DNS lookup tool.
- If nothing comes back, recheck spelling and the name the record was published under. Some DNS panels append the domain automatically, which can double it.
- If a record comes back, confirm that p= is filled, that v=DKIM1 is the first tag, and that a long value was not damaged when split into strings.
- If key and signature both exist and verification still fails, ask whether the message changed in transit. A mail gateway that appends a footer or reformats the body shows up as a body hash mismatch.
Troubleshooting checklist
- Is d= your domain, or deliberately the service's?
- Is there exactly one TXT record for the selector?
- Is the p= value complete?
- Does h= include From?
- Is the key at least 1024 bits, and 2048 where possible?
- Have unused selectors been cleaned up?
A DKIM log for every system that signs
A site's mail can leave from a newsletter tool, a web server, a helpdesk and an invoicing system. Each may have its own signature, selector and key lifecycle. Without a log, an old key sits in DNS for years after the tool is gone.
A simple table
| System | d= value | s= value | Owner | Date added | Rotation note |
|---|---|---|---|---|---|
| Newsletter tool | Your domain | Selector from the tool | Marketing lead | Write the date | New selector if the tool changes |
| Web server | Your domain | Your own selector | Technical lead | Write the date | Write a rotation plan |
| Helpdesk | Your domain or the tool's | Selector from the tool | Support lead | Write the date | Note whether alignment is needed |
Naming selectors
The RFC does not prescribe selector names; it only says a domain can hold several at once. Practical suggestion: use a readable name with the system and the year, such as newsletter2026, so that anyone reading DNS can tell which record belongs to which system and period. Do not rename a selector a service requires.
How often to rotate
Neither RFC 6376 nor the Gmail page sets a rotation interval, so a rule such as "rotate yearly" has no support in them. Practical suggestion: set your own schedule and, at minimum, rotate when you change services, when a person with access leaves, or when the private key may have reached someone else. If the service holds the private key for you, your options depend on what the service offers.
Keeping the log current
- Add a tool to the log before it starts sending as your domain.
- Remove its record from the log and from DNS when you drop it.
- Each quarter, resend test messages and confirm d= and s= again.
DKIM next to SPF
The two methods answer different questions and do not replace one another.
| Feature | SPF (RFC 7208) | DKIM (RFC 6376) |
|---|---|---|
| What it checks | The sending IP against the HELO and MAIL FROM identity | That signed headers and body are unchanged, and which domain signed |
| DNS record | TXT on the domain itself | TXT at selector._domainkey.domain |
| Sender side needs | Authorized IPs and services | A system that signs with a private key |
| Several records | One per domain, or permerror | One per selector; several keys can be active |
| Gmail expectation | SPF or DKIM; both at 5,000 or more per day | Same |
Mistakes that recur
| Mistake | Result | Fix |
|---|---|---|
| Misspelled selector or domain | No key found, PERMFAIL | Compare s= and d= with the DNS name |
| Truncated p= value | Signature will not verify | Copy the whole value, split into strings if needed |
| Reusing a selector for a new key | Old and new signatures blur (RFC advice) | One new selector per key |
| Leaving signing under the tool's domain | DKIM passes, alignment fails | Verify your domain in the tool |
| Old service's key left in DNS for years | An unused key stays valid (practical suggestion) | Remove it or empty p= after the move |
Around the signature
A valid signature does not decide inbox placement; the Gmail page lists SPF, DKIM, DMARC, alignment, spam rate and unsubscribe handling as separate requirements. If the newsletter carries sponsored blocks, our note on sponsored content disclosure covers labeling. Audience figures you share with advertisers belong in a website media kit, and click reporting for newsletter links is easier to read with consistent tags, as described in our post on sponsored-post reporting with UTM and Search Console.
Frequently Asked Questions
What does a DKIM signature actually prove?
According to RFC 6376, a valid signature shows that the signed content has not changed since it was signed. It does not on its own prove that the signing domain is the same as the visible From domain; DMARC alignment makes that link.
What is a DKIM selector and how is it chosen?
The selector is the s= tag in the DKIM-Signature header and tells the receiver which key record to look up. The key name is the selector, then ._domainkey., then the domain. If a sending service signs for you, the service tells you which selector to publish.
How long should a DKIM key be?
RFC 6376 says signers must use keys of at least 1024 bits for long-lived keys. The Gmail page requires 1024 bits or longer to send to personal Gmail accounts and recommends 2048 bits if your domain provider supports it.
DKIM passes but DMARC fails. Why?
Most likely the signature was made under the sending tool's domain, so it is not aligned with your From domain. Verify your domain inside the tool and publish the records it provides, so that d= shows your own domain.
When can I delete the old DKIM record after changing services?
First publish the new service's key and confirm sending works, then stop sending through the old service and keep the old key record long enough for verification to finish. The RFC gives no number of days. After that, remove the record or revoke it by emptying p=.
How do I troubleshoot a DKIM failure?
Take d= and s= from the DKIM-Signature line in the raw header, query the TXT record at s, ._domainkey., d, confirm that p= is filled and that From appears in h=. If the key is fine, check whether the message was changed in transit.
Conclusion
A DKIM signature shows that signed content did not change after signing; the signing domain and selector point to a public key in a TXT record at selector._domainkey.domain. A valid signature does not by itself show that the From domain is yours, because that link comes from DMARC alignment, so set up each sending tool to sign under your own domain. When rotating keys, publish a new selector first, switch signing, keep the old key long enough for verification and only then remove it. When something fails, rebuild the key name from the raw header and query DNS; that separates a DNS problem from a message problem quickly.
If you want your newsletter audience to reach advertisers, you can browse guest post listings on Akua Adforce; scope and terms are written on each product page.
Post a comment
Please log in to leave a comment. Login