Recently Updated: 17 min read

DKIM Explained: Selectors, Public Keys and Signatures

DKIM Explained: Selectors, Public Keys and Signatures

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.

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

TagMeaningDetail from RFC 6376 section 3.5
v=VersionMust be 1
a=AlgorithmSigners 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=SelectorRequired
h=Signed header namesFrom must be included (section 5.4)
bh=Body hashHash of the canonicalized body
b=Signature dataTreated as empty while the signature is computed
c=CanonicalizationDefaults to simple/simple
t=, x=Timestamp, expirationBoth recommended; x= is not intended as an anti-replay defense
i=Agent or user identityOptional; its domain must be the same as or a subdomain of d=
z=Copied header fieldsFor 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

TagMeaningDetail
v=Record versionIf present, DKIM1 and the first tag
k=Key typeDefaults to rsa
p=Public key, base64An empty value means the key has been revoked
h=Acceptable hash algorithmsDefault allows all
s=Service typesDefault is *; email is the defined type
t=Flagsy marks testing mode; s restricts the identity domain to match exactly
n=NotesFor 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.

  1. Find the domain or sender authentication section in the service and add your domain.
  2. 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.
  3. 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.
  4. Press the verify button in the service.
  5. Send a test message to yourself and confirm that the DKIM-Signature header shows your domain in d=.
  6. Repeat for every other system that sends with your domain.

Setup check at a glance

CheckExpectedIf not
Selector record in DNSOne TXT record with a filled p= valueCopy name and value again
d= in the test messageYour domainFinish domain verification in the service
s= in the test messageThe selector the service namedCompare with the service documentation
From in the h= listPresentContact the service
Key lengthAt least 1024 bits, 2048 if offeredAsk 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

  1. Choose a new selector for the new key and publish its public key. Leave the old selector and key in place.
  2. After DNS has updated, switch the sending system to sign with the new private key and selector.
  3. 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.
  4. 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

StepNew serviceOld service
1Publish its DKIM recordsLeave alone
2Confirm d= and s= in test messagesKeeps sending
3Start sendingStop sending
4MonitorKeep its key record for a while
5Normal operationRemove or revoke its key record

Decision rule: new key or new selector

  1. Never write a new key under an old selector; every new key gets a new selector.
  2. When changing services, use the selector the service tells you to use.
  3. 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

SituationRFC outcomeLikely cause
No key foundPERMFAIL, no key for signature (6.1.2)Misspelled selector or domain, record not published
Key temporarily unavailableTEMPFAIL, key unavailable (6.1.2)Transient DNS problem
Body hash mismatchPERMFAIL, body hash did not verify (6.1.3)Body changed after signing
Signature mismatchPERMFAIL, signature did not verify (6.1.3)Header changed or key does not match
From not signedPERMFAIL, From field not signed (6.1.1)From missing from h=
Revoked keyFailed 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

  1. Send a test message and open the raw headers. Note d= and s= in the DKIM-Signature line.
  2. Build the key name: s value, then "._domainkey.", then d value. Query that name's TXT record with a DNS lookup tool.
  3. 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.
  4. 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.
  5. 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

Systemd= values= valueOwnerDate addedRotation note
Newsletter toolYour domainSelector from the toolMarketing leadWrite the dateNew selector if the tool changes
Web serverYour domainYour own selectorTechnical leadWrite the dateWrite a rotation plan
HelpdeskYour domain or the tool'sSelector from the toolSupport leadWrite the dateNote 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.

FeatureSPF (RFC 7208)DKIM (RFC 6376)
What it checksThe sending IP against the HELO and MAIL FROM identityThat signed headers and body are unchanged, and which domain signed
DNS recordTXT on the domain itselfTXT at selector._domainkey.domain
Sender side needsAuthorized IPs and servicesA system that signs with a private key
Several recordsOne per domain, or permerrorOne per selector; several keys can be active
Gmail expectationSPF or DKIM; both at 5,000 or more per daySame

Mistakes that recur

MistakeResultFix
Misspelled selector or domainNo key found, PERMFAILCompare s= and d= with the DNS name
Truncated p= valueSignature will not verifyCopy the whole value, split into strings if needed
Reusing a selector for a new keyOld and new signatures blur (RFC advice)One new selector per key
Leaving signing under the tool's domainDKIM passes, alignment failsVerify your domain in the tool
Old service's key left in DNS for yearsAn 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.

0 Comments

No comments yet for this article.

Post a comment

Please log in to leave a comment. Login