DKIM Selectors Explained: The s= Tag, the _domainkey DNS Label Tree, and the Multi-Selector Pattern (RFC 6376 Section 3.1 / Section 3.6.1)
The DKIM selector vocabulary reference: the selector identifier (RFC 6376 section 3.1) named in the s= tag of the DKIM-Signature header, the <selector>._domainkey.<domain> DNS label tree where the public key is published as a TXT record (RFC 6376 section 3.6.1), the every-tag reference for the published selector record (v=DKIM1, k=rsa, p=, t=, h=, s=, n=), the eight selector-naming patterns operators encounter, the provider selector catalogue for Microsoft 365 / Google Workspace / Amazon SES / SendGrid / Mailgun / Mailchimp / Postmark / SparkPost / Klaviyo / HubSpot / Brevo, the multi-selector / multi-vendor deployment model, the dual-selector zero-downtime rotation pattern, and the seven most common selector-related failures with symptom / diagnosis / fix for each. The canonical answer to DKIM selector debugging.
This reference is provided in English. DKIM is specified in an English-language RFC (RFC 6376) and the canonical selector vocabulary (selector, _domainkey, s=, d=, v=DKIM1, k=rsa, p=, t=y, t=s) does not translate. We keep the body in the source language so technical terms remain consistent with the specifications.
TL;DR
- A DKIM selector is a short label
that names a specific public key for a signing
domain. Defined as the
s=tag value in theDKIM-Signatureheader (RFC 6376 §3.1), the selector is what makes multiple active DKIM keys possible for a single domain. - DNS location: the public key is
published as a TXT record at the DNS name
<selector>._domainkey.<domain>. The_domainkeyinfix is the canonical anchor defined in RFC 6376 §3.6.2. Example:selector1._domainkey.example.com. - The s= tag in the DKIM-Signature
header tells the verifier which selector to look
up. Combined with the
d=tag (signing domain), the verifier constructs the DNS query<s_value>._domainkey.<d_value>and retrieves the TXT record containing the public key (thep=tag in that record). - The selector TXT record tags
(RFC 6376 §3.6.1):
v=DKIM1(version, mandatory),k=rsa(key type, alsok=ed25519per RFC 8463),p=<base64-public-key>(mandatory), and the optionalt=y(test mode),t=s(strict alignment betweend=andi=),h=sha256,s=email,n=<notes>. - Provider selector catalogues:
Microsoft 365 uses
selector1andselector2(CNAME-pointed at.onmicrosoft.com); Google Workspace usesgoogleby default; Amazon SES Easy DKIM uses three CNAMEs ending in.dkim.amazonses.com; SendGrid usesem<n>ands1/s2; Mailgun usesk1ormailo; Mailchimp usesk1; Postmark uses date-based labels; SparkPost usesscph<yyyymm>; Klaviyo usesklaviyo1; HubSpot useshs1-<...>; Brevo usesmail. - The dual-selector rotation pattern depends on selectors enabling zero-downtime key changes: publish the new selectors public key in DNS, switch the signer to use the new selector, wait for the cache TTL to drain on the old selector, then retire the old selector. See DKIM key rotation for the full procedure.
- The seven most common selector failures:
(1) NXDOMAIN (selector record never published or
wrong DNS zone); (2) wrong selector name in the
DKIM-Signature header; (3) stale selector after
rotation; (4) 255-byte TXT-record split pitfall
corrupting the base64 key; (5) CNAME-vs-TXT
confusion at the DNS provider; (6) wildcard-mask
interference (
*.example.comA/AAAA records do not affect TXT but*._domainkeywildcards do); (7) DNS propagation lag immediately after publishing a new selector. Each is documented in section 10 with symptoms, diagnosis steps, and operational fixes.
1. Overview: why DKIM has selectors
DKIM signs outbound mail with a private key, and the
receiver verifies the signature by fetching the
corresponding public key from the senders DNS. The
obvious DNS-only design would be to publish a single
public key per signing domain at a fixed well-known
name (e.g.
_dkim.example.com). RFC 6376 deliberately
chose a more elaborate scheme: the public key is
published at
<selector>._domainkey.<domain>,
where the selector is a short label chosen by
the signer. The DKIM-Signature header carries both the
signing domain (d=) and the selector
(s=); the verifier combines them with the
_domainkey infix to construct the DNS
query.
The selector level of indirection exists because a real-world domain almost always has more than one DKIM key in active use simultaneously:
- Multi-vendor deployments. A
typical mid-size business sends mail from
Microsoft 365 (corporate mail), Mailchimp
(marketing newsletters), SendGrid (transactional
notifications), and an internal Postfix server
(server-generated alerts). Each sender owns its
own private key and signs with its own selector;
each publishes the corresponding public key under
the same root signing domain (e.g.
example.com) at a different selector name. Selectors are the namespacing mechanism that allows the samed=example.comdomain to host four independent public keys. - Zero-downtime key rotation. Cryptographic best practice requires regular key rotation to limit the blast radius of a key compromise and to keep up with evolving algorithm recommendations (RFC 8301 forbade rsa-sha1 and recommends RSA keys of at least 2048 bits; Ed25519 was introduced by RFC 8463). Rotating without downtime requires publishing the new key BEFORE switching the signer to use it — which means both the old and the new key must be in DNS simultaneously. Selectors enable this: the old key stays at the old selector, the new key is published at a new selector, the signer is switched, and the old selector retires only after the cache TTL drains. See DKIM key rotation for the full dual-selector procedure.
- Per-purpose key isolation. Security-conscious operators issue distinct keys for distinct purposes (newsletter signing, transactional signing, corporate-mail signing). A compromise of one private key (a misconfigured marketing-automation vendors API key, a stolen SaaS-sender token) contains the blast radius to the one signer that owned that key; the corporate mail keeps signing with a separate key under a separate selector.
- Per-region key separation.
Multi-region operators sometimes separate signing
infrastructure by region for latency or regulatory
reasons (EU signing in EU servers, US signing in
US servers). Each region gets its own selector;
the signing domain stays the same; DMARC
alignment continues to bind both selectors to the
same
From:organisational domain. - Per-message-class key isolation. Some operators issue per-application-tier selectors (production vs staging vs development). Staging mail never reaches the production selector, so a misconfigured staging signer cannot accidentally invalidate production signatures.
Without selectors, every one of these multi-key deployments would require some other namespacing mechanism. RFC 6376 chose to bake selectors into the protocol because every real-world deployment needs them.
The trade-off is mechanical: every selector lookup is one extra DNS query the receiver must perform during verification. In practice this is essentially free (the selector TXT cache locally per receiver), and the operational benefit of multi-key support vastly outweighs the lookup cost.
2. The
<selector>._domainkey.<domain>
DNS label tree
DKIM public keys live under a dedicated DNS label
anchor: the _domainkey infix. RFC 6376
§3.6.2 chose the underscore-prefixed
_domainkey label so the DNS namespace for
DKIM keys is unambiguously distinguishable from
ordinary hostnames (underscore-prefixed labels are
reserved for protocol-defined service records — see
also _dmarc,
_smtp._tls, _mta-sts,
_caa).
The canonical label structure:
<selector>._domainkey.<domain>.
A signer with
d=example.com and
s=selector1 publishes the public key at
the DNS name selector1._domainkey.example.com.
The verifier reads the DKIM-Signature header, extracts
the d= and s= values,
concatenates them with the _domainkey
infix, and issues a DNS TXT query at that name.
Worked examples by signing scenario:
| Scenario | d= (signing domain) |
s= (selector) |
DNS lookup name |
|---|---|---|---|
| Microsoft 365 root domain | example.com |
selector1 |
selector1._domainkey.example.com |
| Microsoft 365 rotation buffer | example.com |
selector2 |
selector2._domainkey.example.com |
| Google Workspace default | example.com |
google |
google._domainkey.example.com |
| Amazon SES Easy DKIM (one of three) | example.com |
abcdef1234567890 (16-hex) |
abcdef1234567890._domainkey.example.com |
| SendGrid CNAME (one of three) | example.com |
s1 |
s1._domainkey.example.com |
| Mailgun default | mg.example.com |
k1 |
k1._domainkey.mg.example.com |
| Postmark date-based | example.com |
20240301 |
20240301._domainkey.example.com |
| OpenDKIM self-hosted, dated | example.com |
jan2026 |
jan2026._domainkey.example.com |
Notice the Mailgun row: when a provider signs mail under a
subdomain (here mg.example.com, and likewise
any service set up on a subdomain such as
em1234.example.com) rather than the root
domain, the d= tag is the subdomain and the
selector is published under it. DMARC alignment uses the
organisational domain (example.com) so the
subdomain still aligns relaxed; strict alignment fails
unless the From: address is in that same subdomain.
The label is case-insensitive (DNS labels are
case-insensitive per
RFC 4343),
so Selector1._domainkey.example.com and
selector1._domainkey.example.com resolve
to the same record. By convention selectors are
lowercase in both DKIM-Signature headers and DNS
records.
5. The eight selector-naming patterns operators encounter
RFC 6376 §3.1 specifies the syntax of a selector name (a DNS label sequence) but does not prescribe a naming convention. Over time eight broad naming patterns have emerged. Recognising the pattern tells operators what the selector probably means and how to rotate it.
5.1 The numbered-pair pattern (selector1 / selector2)
Pattern: two selectors numbered sequentially; one is active at any given time, the other is the rotation buffer.
When to use: any deployment where the operator wants a clean dual-selector rotation workflow. Microsoft 365 follows this pattern as the default; many self-hosted OpenDKIM operators copy it.
Operator workflow: at rotation time, generate a new key, publish at the non-active selector, switch the signer to use the non-active selector, retire the previously-active selector after the cache TTL drains.
Pitfalls: the numbered-pair pattern
requires DISCIPLINE about which selector is currently
active — operators sometimes lose track. A label like
n=Microsoft 365 active selector as of
2026-01-15 in the TXT helps.
5.2 The date-based pattern (20240301 / jan2026 / mar2026)
Pattern: the selector name is the
rotation date (ISO-8601 20240301, short
mar24, or descriptive mar2026).
When to use: self-hosted signers with a regular rotation cadence (quarterly, semi-annual, annual). Postmark uses this pattern for its provider-managed selectors.
Operator workflow: name the new
selector after the rotation date; the date is the
audit log entry — anyone reading
jan2026._domainkey.example.com in a
DKIM-Signature header knows the key was deployed in
January 2026.
Pitfalls: the date naming pattern
creates noise over years (a long-lived domain
accumulates many old jan2024,
jul2024, jan2025 records).
Retire old selectors aggressively after the rotation
cache TTL drains.
5.3 The provider-named pattern (google / mailgun / mailchimp)
Pattern: the selector name is the name of the provider that owns the key.
When to use: any multi-vendor
deployment where operators want the DKIM-Signature
header to be self-documenting — reading
s=google on a message tells the reader
Google Workspace signed it.
Operator workflow: generate a selector named after the provider when onboarding that provider; retire when offboarding the provider.
Pitfalls: the provider-named pattern
encodes the vendor relationship into DNS, which
creates a small information disclosure (anyone
enumerating _domainkey records can see
which providers you use). For most operators this is
not a concern; for security-conscious operators
consider opaque selector names.
5.4 The short-letter pattern (s1 / s2 / k1 / k2 / em1)
Pattern: a short prefix letter
followed by a number. SendGrid uses s,
Mailgun uses k, Mailchimp uses
k, some legacy signers use
dk.
When to use: provider-managed deployments where the provider chose the convention — operators inherit the pattern from the provider.
Operator workflow: follow the
providers documented value; the provider will tell
you to publish s1._domainkey.example.com
(SendGrid) or k1._domainkey.example.com
(Mailgun) and gives you the corresponding CNAME or
TXT value.
Pitfalls: short-letter selectors are easy to mistype; selector1 vs selecter1 typos cause NXDOMAIN failures.
5.5 The opaque-identifier pattern (Amazon SES abcdef1234567890; SparkPost scph0717)
Pattern: a long alphanumeric string
that the provider generates and the operator does
not interpret. Amazon SES Easy DKIM uses three
16-hex tokens per signing domain; SparkPost uses
scph<yyyymm>.
When to use: provider-managed deployments where the provider rotates keys transparently and the operator does not need to track which selector is active.
Operator workflow: publish the three CNAMEs the provider gives you (Amazon SES) or the single TXT the provider gives you (SparkPost); the provider rotates without operator intervention.
Pitfalls: the operator cannot inspect the selector to determine what it is for — the opaque identifier needs operator-side documentation linking it to the vendor relationship.
5.6 The purpose-based pattern (newsletter / transactional / corporate)
Pattern: the selector name describes the mail stream the key signs.
When to use: security-conscious operators who want per-purpose key isolation (compromise of the newsletter key does not affect transactional signing).
Operator workflow: issue one selector per mail stream; route each stream through a signer configured to use only its assigned selector.
Pitfalls: requires consistent routing discipline — if your transactional mail accidentally goes through the newsletter signer, the receiver sees an unexpected selector and DMARC alignment may differ.
5.7 The Microsoft-365-style hyphenated pattern (selector1-example-com)
Pattern: a Microsoft-365 specific
convention where the CNAME target encodes the
customer domain into the selector name with dots
replaced by hyphens (so
selector1._domainkey.example.com
CNAMEs to selector1-example-com._domainkey.<tenant>.onmicrosoft.com).
When to use: only relevant if you operate Microsoft 365 — Microsoft mandates this pattern as the CNAME target.
Operator workflow: at custom-domain onboarding, the Defender portal generates the correct CNAME target with the hyphen substitution pre-computed. Operators copy-paste the CNAME values without computing the hyphenated form themselves.
Pitfalls: only applies inside Microsoft 365; do not reproduce this pattern in self-hosted deployments.
5.8 The hosted-service prefix pattern (HubSpot hs1-<...>; Klaviyo klaviyo1)
Pattern: the selector includes the
provider name as a prefix plus a sequence or hash
suffix. HubSpot uses
hs1-<customer-tenant-id>;
Klaviyo uses klaviyo1.
When to use: provider-managed deployments where the provider needs to multi-tenant the selector under your domain.
Operator workflow: publish the selector the provider gives you; the prefix tells you which provider published it.
Pitfalls: as with provider-named selectors, the prefix exposes the vendor relationship via DNS.
6. The provider selector catalogue
A catalogue of the selector names operators encounter in the major email-sending providers. Use this table when reading an unfamiliar DKIM-Signature header to identify the signer, or when onboarding a new provider to know which CNAME or TXT records to publish.
| Provider | Selector(s) | DNS record type | Operator publishes | Rotation model |
|---|---|---|---|---|
| Microsoft 365 (Exchange Online) | selector1 / selector2 |
CNAME → .onmicrosoft.com |
Two CNAMEs:
selector1._domainkey.<your-domain>
CNAMEs to
selector1-<your-domain-hyphenated>._domainkey.<tenant>.onmicrosoft.com;
same pattern for selector2. |
The administrator starts a rotation in the
Defender portal; signing then moves between
selector1 and
selector2, with no DNS change. |
| Google Workspace (Gmail) | google (default), custom on
request |
TXT | One TXT at
google._domainkey.<your-domain>
with the value Google generates in the
Admin Console (Apps > Google Workspace
> Gmail > Authenticate email). |
Google supports rotation via a second
custom selector; the operator generates
the new key in the Admin Console,
publishes alongside google,
switches active in Admin Console. |
| Amazon SES (Easy DKIM) | Three 16-hex tokens (e.g.
abc123def456...) |
CNAME → .dkim.amazonses.com |
Three CNAMEs:
<token>._domainkey.<your-domain>
CNAMEs to
<token>.dkim.amazonses.com
for each of the three tokens SES
generates per signing identity. |
SES rotates transparently — operators do not manage the rotation schedule directly; AWS rotates and republishes the CNAMEs. |
| SendGrid | s1 / s2, plus the
em<n> subdomain |
CNAME → .sendgrid.net |
Three CNAMEs generated by SendGrid:
em<n>.example.com →
u<n>.wl.sendgrid.net,
s1._domainkey.example.com →
s1.domainkey.u<n>.wl.sendgrid.net,
s2._domainkey.example.com →
s2.domainkey.u<n>.wl.sendgrid.net. |
SendGrid handles rotation between
s1 and s2
transparently; operators do not
intervene. |
| Mailgun | k1 /
mailo /
pic (legacy) |
TXT | One TXT at
k1._domainkey.mg.example.com
with the key value Mailgun shows in
Sending Domains > DNS records. |
Operator rotates by adding a new selector through Mailguns DKIM rotation tool. |
| Mailchimp | k1 (default) |
CNAME → .dkim.mcsv.net |
One CNAME at
k1._domainkey.example.com
pointing to
dkim.mcsv.net. |
Mailchimp manages rotation behind the CNAME; operators do not see selector changes. |
| Postmark | Date-based (e.g.
20240301) |
TXT | One TXT per signing domain with the provider-generated key value. | Postmark issues a new date-based selector when rotating; operators publish the new record alongside the old until cache drains. |
| SparkPost | scph<yyyymm> (e.g.
scph0717) |
TXT | One TXT at
scph0717._domainkey.example.com
with the SparkPost-generated key. |
SparkPost rotates by issuing a new
scph<newer-date>
selector and migrating signing to it. |
| Klaviyo | klaviyo1 (and
klaviyo2 for rotation) |
CNAME → .klaviyomail.com |
One or two CNAMEs at
klaviyo<n>._domainkey.example.com
pointing to Klaviyo-managed targets. |
Klaviyo manages rotation behind the CNAMEs. |
| HubSpot | hs1-<customer-token> /
hs2-<customer-token> |
CNAME → .hs.bounce /
.dkim.hubspot |
Two CNAMEs per signing domain with tenant-specific tokens HubSpot generates. | HubSpot manages rotation behind the CNAMEs. |
| Brevo (formerly Sendinblue) | mail |
CNAME → .b.brevo.com |
One CNAME at
mail._domainkey.example.com
pointing to the Brevo-managed target. |
Brevo manages rotation behind the CNAME. |
The DMARC Analyzer Domain Security Checker automatically resolves the published selectors for a domain and identifies which provider each selector belongs to — useful for auditing a deployment after a vendor change or for surfacing forgotten selectors from past vendors.
7. The multi-selector / multi- vendor deployment model
Almost every production domain runs more than one DKIM-signing path simultaneously. The selector mechanism is the namespacing primitive that makes multi-vendor coexistence possible.
A canonical multi-vendor deployment for a typical
mid-size business sending under
example.com:
| Mail stream | Sender | Selector under example.com |
DNS record |
|---|---|---|---|
| Corporate mail (HR, finance, executive) | Microsoft 365 (Exchange Online) | selector1,
selector2 |
CNAME → .onmicrosoft.com |
| Marketing newsletters | Mailchimp | k1 |
CNAME → .dkim.mcsv.net |
| Transactional notifications (password resets, receipts) | Postmark | 20240301 |
TXT (provider-generated) |
| Server-generated alerts (cron output, fail2ban, monitoring) | Self-hosted Postfix + OpenDKIM | postfix1 |
TXT (operator-generated) |
All four signers share the same d=
domain (example.com) but each uses a
distinct selector. The
_domainkey.example.com subtree
accommodates all four selector records without
conflict. Receivers verify each message by reading
the s= tag and fetching the
corresponding selector record.
The DMARC implications:
- One DMARC policy at
_dmarc.example.comcovers all four signers. The policy applies to theFrom:header organisational domain, not per-signer. - DKIM alignment is per-signature. A
message signed by Microsoft 365 with
d=example.comands=selector1aligns withFrom: someone@example.comin relaxed and in strict mode, because the domains are identical. A message signed by Mailchimp withd=example.comands=k1aligns identically. The selector itself is not involved in alignment — thed=tag is. - SPF and DKIM both contribute to alignment. SPF authorises the sending IP; DKIM authorises the cryptographic signature. Multi-vendor deployments typically rely on DKIM alignment for the bulk of senders because each vendor needs IP space SPF cannot tractably include (DKIM has no 10-lookup limit problem).
See DMARC alignment explained for the full alignment semantics, and SPF lookup limit explained for why multi-vendor deployments typically rely on DKIM alignment more than SPF alignment.
8. The dual-selector zero-downtime rotation pattern
Rotating a DKIM key without breaking signature verification on in-flight mail requires publishing the new key BEFORE switching the signer to use it. The selector mechanism is the protocol primitive that enables this — the new key gets published at a new selector, the signer is switched to the new selector, and the old selector retires only after the cache TTL drains.
The canonical six-step procedure:
- Generate the new key pair.
Self-hosted:
openssl genrsa 2048oropendkim-genkey -s newselector -d example.com. Provider-managed: rotate inside the providers admin console (Microsoft 365 Defender portal, Google Workspace Admin Console, etc.). - Choose the new selector name.
Follow the pattern (numbered-pair if the
current is
selector1, date-based if the current isjan2026, etc.). - Publish the new selectors public key
at
<new-selector>._domainkey.example.com. Verify the TXT record resolves withdig +short TXT <new-selector>._domainkey.example.com. - Wait for DNS propagation. Typically 5-15 minutes, capped at the parent zone TTL. Confirm propagation by querying from multiple recursive resolvers (Cloudflare 1.1.1.1, Google 8.8.8.8, your local resolver).
- Switch the signer to the new selector.
OpenDKIM: update
KeyTableandSigningTableto reference the new selector, reload OpenDKIM. Provider-managed: toggle the active selector in the providers admin console. - Retire the old selector after the cache
TTL drains. Wait at least
2 × max(TTL)for in-flight signatures to propagate (typical: 24-48 hours is conservative). Delete the old selector TXT record. Verify the signer no longer references it.
The DMARC Analyzer DKIM key rotation page documents the full procedure with per-provider variants and the emergency single- selector hot-swap. The key insight here is that the selector mechanism is the protocol primitive underlying the entire rotation playbook — without selectors, zero-downtime rotation would not be possible.
9. The seven most common selector failures
Every selector-related DKIM verification failure falls into one of seven canonical patterns. Recognising the pattern accelerates diagnosis from hours of guesswork to minutes of targeted investigation.
9.1 Selector NXDOMAIN
Symptom: the verifier reports
dkim=permerror or
dkim=none in the
Authentication-Results header with a reason like
(no key for signature) or
(selector not found). The receivers
DNS query for
<selector>._domainkey.<domain>
returns NXDOMAIN.
Diagnosis: run
dig +short TXT <selector>._domainkey.<domain>.
If the answer is empty, the record does not exist at
the authoritative resolver. If dig +trace
shows NXDOMAIN at the authoritative server, the
selector was never published or was published at the
wrong zone. If dig +short returns a
valid record from the authoritative server but the
receivers resolver still sees NXDOMAIN, suspect a
transient DNS-provider propagation lag or a stale
negative cache.
Fix: publish the TXT (or CNAME) at
the correct DNS name. Verify with
dig +short TXT from multiple recursive
resolvers. If a stale negative cache is suspected,
wait the SOA negative-cache TTL (typically 5 minutes
to 1 hour).
9.2 Wrong selector name in the DKIM-Signature header
Symptom: the verifier reports
NXDOMAIN, but
dig +short TXT <canonical-selector>._domainkey.<domain>
returns a valid record. The mismatch is between
what the signer emitted (s=<typo>)
and what was published in DNS.
Diagnosis: read the
s= tag in the failing message
DKIM-Signature header. Compare to the actual selector
name in DNS. Typos are common —
selecter1 vs selector1,
googel vs google,
scph0717 vs scph717.
Fix: correct the signer
configuration. OpenDKIM: fix the
KeyTable entry. Provider-managed: the
provider control panel typically prevents typos at
UI entry, so a typo at the signer-side usually
indicates a misconfigured custom signer.
9.3 Stale selector after rotation
Symptom: the verifier reports NXDOMAIN immediately after a key rotation. The signer is using the new selector but the new selectors public key has not propagated yet (or was never published).
Diagnosis: read the
DKIM-Signature header on a failing message. Verify
the s= tag matches the new selector you
intended to use. Verify
dig +short TXT
<new-selector>._domainkey.<domain>
returns the new key. If not, the rotation procedure
skipped step 3 (publish the new selectors public
key) or step 4 (wait for DNS propagation) — the
signer switched before the key was reachable.
Fix: publish the new selectors
public key, then wait for propagation, then verify
with dig, THEN switch the signer.
Follow the six-step procedure in
section 8.
9.4 The 255-byte TXT-record split pitfall
Symptom: the verifier reports
dkim=permerror with a reason like
(key parse error) or
(invalid public key). The selector
record exists and returns content, but the
base64-decoded public key is corrupted.
Diagnosis: run
dig +short TXT <selector>._domainkey.<domain>.
Look for the base64 p= value. If the
base64 string is shorter than expected (less than
300 characters for RSA-2048) or has a clear
truncation point, the DNS provider UI silently
truncated the TXT at the 255-byte boundary. Some
older DNS provider UIs accept a single string longer
than 255 bytes and silently truncate; modern UIs
either reject or wrap into multiple character-strings
correctly.
Fix: at the DNS provider UI, paste the full TXT value as multi-string (each ≤255 bytes, wrapped in double quotes per the BIND zone-file convention). At Cloudflare and Route 53 the UI handles segmentation transparently — paste the full value as one string and the provider multi-segments correctly. At older or legacy DNS providers, manual segmentation is required.
9.5 CNAME-vs-TXT confusion at the DNS provider
Symptom: the operator published a record at the correct name but chose the wrong record type. Either a TXT was published where the provider expected a CNAME (Microsoft 365: published a TXT containing the CNAME target string instead of a CNAME pointing at the target), or a CNAME was published where the provider expected a TXT.
Diagnosis: query dig +short CNAME
<selector>._domainkey.<domain> and
dig +short TXT ... separately; many servers
no longer give a useful answer to ANY
queries. Compare the published record type to what the
provider documentation specifies. A common Microsoft 365
failure is publishing the CNAME target as a TXT value,
which makes the receiver see a TXT containing a hostname
instead of the expected key value.
Fix: delete the wrong-type record; publish the correct-type record. For Microsoft 365 and providers using CNAME-based selectors, this means a literal CNAME pointing at the provider-supplied target — not a TXT containing the CNAME target as text.
9.6 Wildcard-mask interference
Symptom: the verifier reports
dkim=permerror with a reason indicating
a TXT record was retrieved but the content is not a
valid DKIM record (no v=DKIM1 prefix,
no p= public key).
Diagnosis: run
dig +short TXT
*._domainkey.<domain>. If the response
matches a configured wildcard
(*.example.com TXT or
*._domainkey.example.com TXT), the
wildcard is shadowing the selector. The receivers
DNS resolver returns the wildcard-matched TXT
instead of an authoritative NXDOMAIN.
Fix: remove the wildcard TXT under
_domainkey.example.com. Wildcards do
not shadow records that are explicitly defined, so
publishing the explicit selector TXT also resolves
the issue — but the wildcard at
*._domainkey is almost never useful
and is best removed.
9.7 DNS propagation lag immediately after publishing
Symptom: a newly-published selector
works at the authoritative resolver
(dig +short TXT at the authoritative
server returns the record) but fails at downstream
recursive resolvers (Gmail, Microsoft 365 mailbox
receiving end). The verifier sees NXDOMAIN for the
first few minutes to hours after publishing.
Diagnosis: run
dig +short TXT
<selector>._domainkey.<domain>
@ns<n>.<ns-provider> against the
authoritative server directly. If the answer is
valid, the issue is propagation — wait for the
parent zone TTL to expire across all caching
resolvers.
Fix: wait for DNS propagation (typically 5-15 minutes for small TTLs; up to 24 hours for legacy 86400-second TTLs). Do NOT switch the signer to a new selector until propagation is confirmed across at least three recursive resolvers (Cloudflare 1.1.1.1, Google 8.8.8.8, Quad9 9.9.9.9). The DNS propagation deep dive covers the cache-behaviour mechanics.
10. FAQ
- What is a DKIM selector?
- A DKIM selector is a short label that names a specific public key for a signing domain. RFC 6376 section 3.1 defines the selector as the s= tag value in the DKIM-Signature header, and the verifier uses the selector together with the signing domain (the d= tag value) to construct a DNS query for the corresponding public key. The DNS label structure is
<selector>._domainkey.<domain>with the public key published as a TXT record at that name. Selectors exist so a single signing domain can publish multiple public keys simultaneously (one per selector), which enables multi-sender deployments (each sender gets a unique selector and the sender owns the corresponding private key), zero-downtime key rotation (publish the new selector first, switch the signer to use it, then retire the old selector after the cache TTL drains), and per-vendor key isolation (a compromise of one vendors selector private key does not affect the others). A selector is the operator-meaningful name (selector1, google, s1, k1, mailo, scph0717) operators see in DKIM-Signature headers and DNS — the s= tag value. - What is the s= tag in a DKIM-Signature header?
- The s= tag in the DKIM-Signature header is the selector identifier. Defined in RFC 6376 section 3.5, the s= tag tells the verifier which selector to look up. Together with the d= tag (signing domain), the verifier constructs the DNS query <s_value>._domainkey.<d_value> and retrieves the TXT record containing the public key (the p= tag in that record). The s= tag value is a domain-style label (lowercase letters, digits, hyphens, dots) and is the operator-visible name of the key the signer used. Reading a DKIM-Signature header, the s= tag is one of the first things to identify — the selector tells you which key signed the message and (combined with d=) where to find the public key in DNS. Modern DKIM-Signature headers always include an explicit s= tag; there is no default.
- Where in DNS is a DKIM selector published?
- A DKIM selector is published as a TXT record at the DNS name
<selector>._domainkey.<domain>. RFC 6376 section 3.6.2 specifies the _domainkey infix as the canonical anchor under the signing domain. For example, a signer with d=example.com and s=selector1 publishes the public key at selector1._domainkey.example.com. The TXT record contains the selector tags: v=DKIM1, k=rsa (or k=ed25519 per RFC 8463), p=<base64-encoded-public-key>, and optionally t= (flags), h= (allowed hash algorithms), s= (service type), n= (notes). Many provider deployments use a CNAME from<selector>._domainkey.<your-domain>to a provider-managed selector hostname instead of a TXT — Microsoft 365 selector1._domainkey.yourdomain.com CNAMEs to selector1-yourdomain-com._domainkey.tenant.onmicrosoft.com; SendGrid s1._domainkey.yourdomain CNAMEs to s1.domainkey.u<n>.wl.sendgrid.net; Amazon SES Easy DKIM uses three CNAMEs ending in .dkim.amazonses.com. CNAME-based selectors avoid the manual TXT-rewrite operators would otherwise need at each provider key rotation. - What does selector1 mean in Microsoft 365 DKIM?
- In Microsoft 365 (Exchange Online), selector1 and selector2 are the two managed selectors Microsoft uses for every DKIM-signing tenant. Only one of them signs at any given time, and the other is needed for key rotation; the administrator starts a rotation, and Microsoft then switches signing to the other selector. The DNS pattern operators publish is two CNAMEs: selector1._domainkey.<your-domain> CNAMEs to selector1-<your-domain-with-hyphens>._domainkey.<tenant>.onmicrosoft.com, and selector2._domainkey.<your-domain> CNAMEs to selector2-<your-domain-with-hyphens>._domainkey.<tenant>.onmicrosoft.com. The hyphen substitution rule is the Microsoft 365 onmicrosoft.com mapping: a custom domain example.com becomes example-com in the target hostname (dots become hyphens). Once both CNAMEs are published and Microsoft has enabled DKIM signing in the Defender portal (Email & collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM), Microsoft 365 signs outbound mail with the active selector, and the verifier resolves the CNAME chain to retrieve the public key Microsoft manages.
- How do I add a new DKIM selector for a new sender?
- The four-step procedure for adding a new selector for a new sender. Step 1: Decide the selector name. Most providers pick the name for you (Microsoft 365 selector1 / selector2, Google Workspace google, SendGrid s1/s2, Amazon SES Easy DKIM domainkey-based CNAMEs); for self-hosted signers you pick a name following the recommended pattern (date-based 20240101, or sequenced k1 / k2, or sender-named newsletter / transactional). Step 2: Generate or obtain the public/private key pair. Self-hosted signers generate RSA-2048 or Ed25519 keys with
openssl genrsa 2048oropendkim-genkey; provider-managed signers expose a copy-paste DNS record value from the provider control panel. Step 3: Publish the public key in DNS as a TXT record (or CNAME for provider-managed) at <selector>._domainkey.<your-domain>. Step 4: Wait for DNS propagation (typically 5-15 minutes, capped at the parent TTL), then enable the signer to use the new selector. The DMARC Analyzer Domain Security Checker verifies the public key is reachable and well-formed; verify the new selector with a test send to a mailbox you control and inspect the DKIM-Signature header for s=<new-selector-name>. - Why does my DKIM verification fail with selector NXDOMAIN?
- A selector NXDOMAIN (no such domain) means the verifier issued a DNS query for <selector>._domainkey.<domain> and the authoritative name server returned NXDOMAIN — no record exists at that name. The five canonical causes: (1) the selector TXT or CNAME record was never published (most common — the operator generated the key but forgot to publish it); (2) the record was published at the wrong DNS zone (publishing at sub._domainkey.example.com when the signer uses sub._domainkey.subdomain.example.com); (3) the record was published with a typo in the selector name (Microsoft 365 selector1 vs selecter1 — the receiver queries the correct name and gets NXDOMAIN); (4) the record was deleted during a maintenance window or DNS provider migration and not restored; (5) the DNS provider is rate-limiting or returning NXDOMAIN for transient reasons (rare — usually a real misconfiguration). The diagnostic command is
dig +short TXT <selector>._domainkey.<domain>at the receivers resolver — if dig returns nothing, the verifier sees NXDOMAIN. The fix is to publish the selector record at the correct name. - Can I have multiple DKIM selectors for the same domain?
- Yes — multiple DKIM selectors per domain is the canonical pattern for almost every production deployment. The selector mechanism is explicitly designed so a single signing domain (d=example.com) can publish multiple selector TXT records simultaneously, one per active key. Common multi-selector scenarios: (1) multi-vendor deployments where each sender (Microsoft 365 + Mailchimp + SendGrid + an internal Postfix) publishes its own selector under the same domain (selector1 / selector2 / k1 / mlsend1 / postfix1); (2) zero-downtime key rotation using a dual-selector pattern (old selector remains until the cache TTL drains, then new selector replaces it); (3) per-purpose key isolation (newsletter signer uses one selector, transactional uses another, corporate mail uses a third — compromise of one private key contains the blast radius); (4) per-region key separation (signing infrastructure in EU vs US uses different selectors). The only constraint is that each selector name must be unique under the same _domainkey. parent — you cannot reuse selector1 for two different keys.
- What is the difference between selector and signing domain?
- The selector and the signing domain are two distinct identifiers in a DKIM-Signature header. The signing domain is the d= tag value — the DNS domain that owns the key, and the domain the verifier uses for DMARC alignment. The selector is the s= tag value — the specific public key under that domain. The verifier combines them with the _domainkey label to construct the DNS query for the public key: <s_value>._domainkey.<d_value>. The signing domain corresponds to organisational identity (which company signed this message); the selector corresponds to which key (newsletter vs transactional, January 2026 vs March 2026, Microsoft 365 selector1 vs Mailchimp k1). DMARC alignment depends on the d= tag matching the From: header organisational domain (strict or relaxed adkim) — selectors are not involved in alignment. A single domain can have many selectors; a selector is meaningless without the signing domain.
- What is the 255-byte TXT record pitfall for DKIM selectors?
- DNS TXT records are limited to 255 octets per individual character-string segment, but the record itself can contain multiple segments concatenated at the DNS protocol layer (RFC 1035 §3.3.14). A DKIM selector public key (especially RSA-2048 or larger) base64-encodes to roughly 392 characters and therefore must be split across two or more 255-byte segments inside the TXT record. The pitfall is at the DNS provider UI: some providers (Cloudflare older UI, some legacy panels) accept a single string longer than 255 bytes in the input box and silently truncate it at the 255-byte boundary, producing a corrupted public key that DKIM verifiers cannot use. The detection signature is a DKIM verification failure where the receiver retrieved the selector TXT but the base64-decoded public key fails to parse as a valid RSA SubjectPublicKeyInfo structure. The fix at most modern providers is to wrap each 255-byte segment in double quotes in the TXT record input (the BIND zone file syntax), which the provider accepts as the multi-string TXT format the resolver concatenates correctly. Verify with
dig +short TXT <selector>._domainkey.<domain>— the output should show the full base64 key without truncation.
12. Verify your DKIM selectors now
The fastest way to confirm every selector under your domain is reachable and well-formed:
- Enumerate the selectors your senders use. List every active sender (Microsoft 365, Google Workspace, Mailchimp, SendGrid, your internal Postfix, etc.) and the selector each sender uses (from the provider admin console or your signer config).
- Resolve each selector record
with
dig +short TXT <selector>._domainkey.<your-domain>. Confirm each returns the expectedv=DKIM1; ...; p=<base64-key>value (or follows a CNAME for provider-managed selectors). - Use the Domain Security Checker to surface all currently- active selectors automatically — it queries the common provider selectors plus any selectors observed in inbound DMARC aggregate reports.
- Inspect a real DKIM-Signature header
with the
Email Header
Analyzer. Send a test message to a mailbox
you control, copy the raw source, and paste
into the analyzer — the DKIM-Signature panel
shows the
s=tag plus the verification verdict for each signed message.