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 the DKIM-Signature header (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 _domainkey infix 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 (the p= tag in that record).
  • The selector TXT record tags (RFC 6376 §3.6.1): v=DKIM1 (version, mandatory), k=rsa (key type, also k=ed25519 per RFC 8463), p=<base64-public-key> (mandatory), and the optional t=y (test mode), t=s (strict alignment between d= and i=), h=sha256, s=email, n=<notes>.
  • Provider selector catalogues: Microsoft 365 uses selector1 and selector2 (CNAME-pointed at .onmicrosoft.com); Google Workspace uses google by default; Amazon SES Easy DKIM uses three CNAMEs ending in .dkim.amazonses.com; SendGrid uses em<n> and s1/s2; Mailgun uses k1 or mailo; Mailchimp uses k1; Postmark uses date-based labels; SparkPost uses scph<yyyymm>; Klaviyo uses klaviyo1; HubSpot uses hs1-<...>; Brevo uses mail.
  • 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.com A/AAAA records do not affect TXT but *._domainkey wildcards 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:

  1. 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 same d=example.com domain to host four independent public keys.
  2. 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.
  3. 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.
  4. 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.
  5. 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.

3. The selector TXT record tags (RFC 6376 §3.6.1)

The published selector record is a TXT record (or a CNAME pointing to one) at <selector>._domainkey.<domain>. The TXT value is a sequence of tag=value pairs separated by semicolons. RFC 6376 §3.6.1 defines the tag set.

Tag Required Meaning Production guidance
v= Recommended Version. Always v=DKIM1 in every modern record. RFC 6376 §3.6.1. If present, it must be the FIRST tag in the record. Always include it; verifiers reject a record whose v= has any other value.
k= Optional (default rsa) Key type. k=rsa for RSA signatures (the default); k=ed25519 for Ed25519 signatures per RFC 8463. Always set explicitly. k=rsa for legacy compatibility, k=ed25519 for compact modern deployments.
p= Mandatory Public key in base64 DER encoding (RSA SubjectPublicKeyInfo or Ed25519 raw key). An empty p= means the selector has been revoked (verifiers MUST treat as signature fail without retrying). The bulk of the TXT record value. Watch for the 255-byte split pitfall (section 10.4) — RSA-2048 base64-encodes to ~392 bytes, exceeds 255 bytes, must be multi-string in the TXT.
t= Optional Flags. t=y means test mode (verifiers must not treat such mail differently from unsigned mail); t=s requires the i= domain to be identical to d= (the i= domain in the signature must not be a subdomain of the d= domain). Remove t=y as soon as production traffic is healthy; leaving test-mode on indefinitely defeats DKIM.
h= Optional Acceptable hash algorithms (colon- separated). Default is all algorithms supported by the signing algorithm (typically sha256 for RSA and Ed25519). Modern signers omit h= (accept-all) or set h=sha256 explicitly. h=sha1 is forbidden by RFC 8301.
s= Optional (default *) Service type. s=email means the key is for email; s=* (the default) means any DKIM-style service. RFC 6376 reserved this for future expansion; in practice always email or default. Omit for default or set s=email explicitly.
n= Optional Human-readable notes about this selector. Verifiers ignore n=; it is a hint for operators reading the record directly. Useful for documenting the selectors purpose (n=Microsoft 365 signing selector, rotated 2026-01) but kept short — the TXT value is already long because of p=.
g= Optional, deprecated Granularity (local-part restriction). Allowed the signer to restrict the selector to specific i= local-parts. Deprecated by RFC 6376 §3.6.1 (carried over from RFC 4871 for backward compatibility). Do not use. Modern signers omit g= entirely.

A canonical production selector TXT record looks like:

selector1._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5..."
                                          "...rest-of-base64-public-key=="

The TXT value is wrapped across two character-strings (each ≤255 bytes) which the resolver concatenates at the protocol layer. Operators publishing through a DNS provider UI must either paste the full value as one string (the UI handles segmentation transparently — Cloudflare, Route 53, Google Cloud DNS) or split the value into two quoted strings matching the BIND zone-file syntax shown above.

4. The s= and d= tags in the DKIM-Signature header

The verifier discovers which selector to use by reading the s= tag in the DKIM-Signature header. The signing domain comes from the d= tag. Both are mandatory per RFC 6376 §3.5.

A canonical production DKIM-Signature header:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=example.com; s=selector1;
        h=from:to:subject:date:message-id;
        bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
        b=H8b...

Reading this header:

  • d=example.com — the signing domain. The verifier uses this for DMARC alignment (the From: header organisational domain must match example.com for the DKIM verdict to align).
  • s=selector1 — the selector. The verifier constructs the DNS query selector1._domainkey.example.com and retrieves the TXT record containing the public key.
  • c=relaxed/relaxed — canonicalization (see DKIM canonicalization).
  • a=rsa-sha256 — algorithm. Confirms the verifier should expect an RSA key under the selector (a k=rsa public key at selector1._domainkey.example.com).
  • bh=... — body hash (see DKIM canonicalization).
  • b=... — signature over canonicalized headers + bh=.

The verifier algorithm is straightforward: parse the d= and s= tags from the DKIM-Signature header, issue a DNS TXT query at <s>._domainkey.<d>, parse the response for the p= public key, recompute the body hash with the canonicalization declared in c= using the algorithm declared in a=, verify the signature against the public key, and emit the verdict.

Why the selector is in the signature header (not derived from the domain): a single signing domain can have many selectors. The DKIM-Signature header is the ONLY place the message itself can declare which selector signed it — without an explicit s= tag, the verifier would not know which of the many possible selector keys to use.

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.com covers all four signers. The policy applies to the From: header organisational domain, not per-signer.
  • DKIM alignment is per-signature. A message signed by Microsoft 365 with d=example.com and s=selector1 aligns with From: someone@example.com in relaxed and in strict mode, because the domains are identical. A message signed by Mailchimp with d=example.com and s=k1 aligns identically. The selector itself is not involved in alignment — the d= 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:

  1. Generate the new key pair. Self-hosted: openssl genrsa 2048 or opendkim-genkey -s newselector -d example.com. Provider-managed: rotate inside the providers admin console (Microsoft 365 Defender portal, Google Workspace Admin Console, etc.).
  2. Choose the new selector name. Follow the pattern (numbered-pair if the current is selector1, date-based if the current is jan2026, etc.).
  3. Publish the new selectors public key at <new-selector>._domainkey.example.com. Verify the TXT record resolves with dig +short TXT <new-selector>._domainkey.example.com.
  4. 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).
  5. Switch the signer to the new selector. OpenDKIM: update KeyTable and SigningTable to reference the new selector, reload OpenDKIM. Provider-managed: toggle the active selector in the providers admin console.
  6. 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 2048 or opendkim-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:

  1. 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).
  2. Resolve each selector record with dig +short TXT <selector>._domainkey.<your-domain>. Confirm each returns the expected v=DKIM1; ...; p=<base64-key> value (or follows a CNAME for provider-managed selectors).
  3. 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.
  4. 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.