Probes every well-known ESP selector in parallel — `google` (Workspace), `selector1`/`selector2` (Microsoft 365), `k1`–`k3` (Mailchimp), `s1`/`em` (SendGrid), `amazonses`, `mte1`/`mte2` (Marketo), `pm` (Postmark), `mg` (Mailgun), `sparkpost`, `sfdc` (Salesforce), and dozens more. No selector required in the input.
Free DKIM checker — auto-scan selectors, grade keys, detect providers, and diagnose fixes.
DKIM Checker probes ~40 well-known selectors (Google Workspace, Microsoft 365, Mailchimp, SendGrid, Amazon SES, Marketo, HubSpot, Postmark, Mailgun, SparkPost, and more) in parallel — no selector required. For each selector that resolves, it decodes the public key via ASN.1 DER parsing (giving you the real RSA modulus bit-length, not the raw base64 byte-count most tools show), classifies the ESP, follows the CNAME delegation chain, flags testing-mode (`t=y`) and revoked keys, and grades the overall domain A–F on the worst selector's key strength. Also includes an email-header paste extractor and a plain-English AI diagnosis with copy-paste key-rotation snippets.
What the tool outputs
Five tabs, eight independent classes of output per DKIM scan. Auto-selector-discovery + accurate ASN.1 modulus math + provider detection + header-paste extraction — no free competitor combines all four.
Grade is derived from the worst selector's real RSA modulus bit-length — parsed from the base64-decoded DER blob (not the flat byte-count competitors report). A = ≥2048-bit. B = 1024-bit (legacy). C = testing mode. D = revoked. F = no DKIM.
Two-tier detection: match the selector name against a known-provider table first, then inspect any CNAME chain target (many ESPs use CNAME delegation — `k1._domainkey.example.com CNAME s1.domainkey.u12345.mail.mailchimpapp.net`).
Paste any `DKIM-Signature:` header from a signed email. Regex parses `d=` (signing domain) and `s=` (selector), pre-fills the lookup, and jumps straight to the exact selector — no guessing required.
`t=y` (testing mode) tells receivers to ignore the signature — a silent deliverability failure most tools miss. Empty `p=` is the RFC 6376 revocation signal, not an error. We surface both correctly.
For selectors delegated via CNAME (typical for Mailchimp, SendGrid, Marketo), we follow the chain and render each hop. The final CNAME target is often the strongest ESP signal we have.
Five aggregate checks: selector present, modern key strength (≥2048), no testing mode, no revoked selectors, sender provider identified. Each with pass/fail + severity (high/med/low).
Summary is 2–3 sentences — 'Three selectors signing mail: google (Google Workspace, 2048-bit), k1 (Mailchimp, 1024-bit — legacy), s1 (SendGrid, 2048-bit). Rotate the Mailchimp key.' Fixes include TXT records + openssl key-rotation shells.
Why DKIM is the identity signature on your mail
DKIM adds a cryptographic signature to every outgoing message. Receivers verify it against your public key in DNS. It's the mechanism that survives forwarding (SPF doesn't) and the one that most bulk-sender rules now require. Five reasons it matters:
- DKIM is the alignment mechanism most receivers actually use. SPF breaks when mail is forwarded — the envelope sender changes to the forwarder. DKIM survives forwarding because the signature is embedded in the message headers. When DMARC evaluates alignment for a forwarded message, DKIM is usually the only mechanism that can pass.
- 1024-bit keys are legacy — modern receivers flag them. NIST deprecated 1024-bit RSA for signature use in 2013. Most enterprises still publish 1024-bit selectors from tools that default to it. Gmail, Yahoo, and Microsoft accept 1024-bit but rank it lower in deliverability scoring. Our grade drops from A to B the moment a 1024-bit key is present.
- Multiple selectors are normal — one hides the others. A real domain publishes 2–8 active selectors: one for Google Workspace, another for the marketing platform, a third for the transactional service, a fourth for the help-desk. Tools that check one selector at a time hide the others. Our scan surfaces the full inventory.
- Testing mode (`t=y`) is a silent kill. When you first set up DKIM, best practice is to publish with `t=y` — telling receivers to accept the signature but not apply enforcement. Teams add `t=y` and forget to remove it. Receivers then quietly ignore the signature. DMARC alignment fails, mail lands in spam. We flag testing-mode as a critical warning.
- Bulk-sender rules now require DKIM. Google/Yahoo's 2024 bulk-sender rules and Microsoft's 2025 alignment both require DKIM signing for senders over 5,000 messages/day — with alignment to the From: domain. A missing or wrongly-aligned DKIM at scale means direct-to-spam.
Parallel selector scan → CNAME follow → ASN.1 decode → grade → AI diagnosis
A DKIM scan is 40 parallel TXT queries with a 1.2s per-query cap, a CNAME chain resolution per hit, a DER structural walk to extract the RSA modulus, and an AI review. Steps in detail:
- Stage 1 — Parallel selector probe Fire ~40 concurrent `<selector>._domainkey.<domain>` TXT queries. Each has a 1.2-second timeout — miss the deadline and the selector is treated as unresolved. The whole scan finishes in ~1.5 seconds regardless of domain.
- Stage 2 — CNAME chain resolution For every selector that resolved, walk the CNAME chain up to 5 hops. Most ESPs (Mailchimp, SendGrid, Marketo) use CNAME delegation — the final target is the strongest ESP fingerprint we have.
- Stage 3 — Multi-string TXT reassembly DKIM public keys are almost always 2048-bit — too long to fit in a single 255-char TXT string. DNS returns them as multiple strings. We join them per RFC 6376 § 3.6.2.2 before parsing.
- Stage 4 — ASN.1 DER decode Split the record on `;`, split each pair on the first `=` (base64 values contain `=` padding), extract `p=` and base64-decode. Walk the DER structure: SEQUENCE → AlgorithmIdentifier → BIT STRING → SEQUENCE → INTEGER (modulus). Strip the leading zero byte. Multiply length by 8. That's your actual key bit-length.
- Stage 5 — Provider detection Two-tier: selector name against a hard-coded rules table (20+ providers), then CNAME target against provider hostname patterns. Order matters — specific rules before generic. `k1` alone hits Mailchimp; a bare `s1` needs the CNAME target to disambiguate SendGrid from generic self-hosted.
- Stage 6 — Grading Per-selector grade: A ≥2048, B 1024, C `t=y`, D revoked. Overall domain grade = worst-of-all. Weakest bit count surfaced separately so users see the exact number that needs attention.
- Stage 7 — AI diagnosis Feed the full selector inventory + grades + providers to the analyzer. Returns a 2–3 sentence plain-English summary, 3–5 imperative recommendations, severity-tagged findings, and copy-paste TXT + shell (`openssl genrsa`) rotation snippets.
How the DKIM grade is computed
Domain grade = worst per-selector grade. This mirrors reality — receivers see every signature, so your weakest key is what protects you at the margin.
- A — Modern (≥2048-bit RSA / Ed25519) All selectors publish keys at 2048-bit or stronger, not in testing mode, not revoked. This is the goal state.
- B — Legacy (1024-bit) At least one selector still uses a 1024-bit key. Rotate to 2048 by publishing a new selector, verifying delivery for a week, then retiring the old one.
- C — Testing mode (t=y) At least one selector has `t=y`. Receivers may ignore the signature entirely. Remove `t=y` once you've validated deliverability.
- D — Revoked (empty p=) At least one selector has an empty `p=` — the RFC-defined revocation signal. Fine if it's intentional (mid-rotation); a problem if you didn't mean to.
- F — No DKIM No selectors resolved. Domain doesn't sign mail, or uses a selector name outside our scan list. Try the Diagnostics tab to paste an email header and extract the exact selector.
SPF vs DKIM vs DMARC — where DKIM fits
SPF authorises IPs, DKIM signs messages, DMARC sets policy. DKIM is the only mechanism that survives forwarding — which is why DMARC increasingly relies on it.
- DKIM — DomainKeys Identified Mail (RFC 6376) Cryptographic signature on outgoing messages. Public key at `<selector>._domainkey.<domain>`. Verifiable by any receiver. Survives forwarding. This is the tool you're looking at.
- SPF — Sender Policy Framework Lists which IPs can send mail for your domain. Breaks under forwarding. See the SPF Checker.
- DMARC — Domain-based Message Authentication, Reporting, and Conformance Policy layer on top of SPF + DKIM. Tells receivers what to do when both fail. See the DMARC Checker.
- Selector Named subkey in the DNS namespace. Lets a domain publish multiple concurrent DKIM keys — one per sending service, one per rotation generation. Examples: `google`, `selector1`, `k1`, `s1`, `mte1`.
- Alignment DMARC-specific. DKIM alignment passes when the DKIM signing domain matches the From: domain (relaxed = organizational-domain match, strict = exact). Alignment is what DMARC actually evaluates.
Every DKIM tag, explained
A DKIM public-key record is a sequence of `tag=value` pairs separated by semicolons. Only `p=` is required in practice; everything else is optional with defaults.
- v=DKIM1 — Version (optional, defaults to DKIM1) Some records omit it; ours accepts either. If present, must be `DKIM1`.
- k= — Key type (default rsa) `rsa` (universal) or `ed25519` (RFC 8463 — smaller, faster, supported by Google and a few others). We surface Ed25519 as `256-bit` because that's its fixed strength.
- p= — Public key (required) Base64-encoded DER SPKI blob (or bare PKCS#1 RSAPublicKey). Empty `p=` is the RFC 6376 revocation signal — the selector is retired, ignore any signature that references it.
- h= — Acceptable hash algorithms (optional, default any) `sha256` is standard. `sha1` is deprecated and increasingly rejected. Colon-separated for multiple: `sha256:sha1`.
- s= — Service type (optional, default `*`) `email` restricts the key to mail signing. `*` allows any service. Most records use the default.
- t= — Flags (optional) `t=y` (testing mode — receivers may accept but not enforce), `t=s` (strict — signing domain must exactly match the i= identity, rarely used). Colon-separated: `t=y:s`.
- n= — Notes (optional) Human-readable annotation. Not evaluated by receivers. Some ESPs use it to embed customer IDs.
Use this programmatically
Every field — selector inventory, per-selector parsed record, provider detection, CNAME chain, key modulus bits, grade, tests, AI diagnosis, fix snippets — is available as JSON.
curl 'https://api.domainscan.in/v1/domain/dkim?domain=microsoft.com'curl 'https://api.domainscan.in/v1/domain/dkim?domain=microsoft.com&selector=selector1'const res = await fetch(
'https://api.domainscan.in/v1/domain/dkim?domain=microsoft.com'
);
const {data} = await res.json();
console.log(data.score.grade); // 'A' | 'B' | 'C' | 'D' | 'F'
console.log(data.score.weakestKeyBits); // e.g. 1024
console.log(data.selectors.length);
// Alert on legacy keys
data.selectors
.filter(s => (s.parsed?.keyLength || 0) < 2048)
.forEach(s => console.warn(`Rotate ${s.selector} (${s.parsed.keyLength}-bit)`));
// Providers signing on your behalf
const providers = new Set(data.selectors.map(s => s.provider));
console.log([...providers]);
// Copy-paste fixes (AI-generated)
(data.AiAnalysis?.fixes || []).forEach(fix => {
console.log(`Fix: ${fix.issue}`);
console.log(fix.snippet);
});{
"found": true,
"domain": "microsoft.com",
"mode": "scan",
"requestedSelector": null,
"selectors": [
{
"selector": "selector1",
"host": "selector1._domainkey.microsoft.com",
"cnames": [{"from": "selector1._domainkey.microsoft.com", "to": "selector1-microsoft-com._domainkey.microsoft.onmicrosoft.com"}],
"found": true,
"dkim": "v=DKIM1; k=rsa; p=MIIBIjANBg...",
"parsed": {
"valid": true,
"version": "DKIM1",
"keyType": "rsa",
"keyLength": 2048,
"keyStrength": "Strong",
"publicKey": "MIIBIjANBg...",
"publicKeyFingerprint": "b4c96aed72f5a831"
},
"provider": "Microsoft 365"
}
],
"selectorsNotFound": [],
"triedSelectors": ["default", "dkim", "..."],
"triedCount": 40,
"score": {
"grade": "A",
"label": "Strong",
"selectorCount": 1,
"weakestKeyBits": 2048
},
"tests": [
{ "test": "DKIM selector present", "passed": true, "severity": "high", "result": "..." },
{ "test": "Modern key strength (≥2048 bit)", "passed": true, "severity": "med", "result": "..." },
{ "test": "Not in testing mode", "passed": true, "severity": "low", "result": "..." },
{ "test": "No revoked selectors", "passed": true, "severity": "low", "result": "..." },
{ "test": "Sender provider identified", "passed": true, "severity": "low", "result": "Detected: Microsoft 365" }
],
"AiAnalysis": {
"summary": "microsoft.com signs mail with one 2048-bit selector delegated to Microsoft 365 tenant DNS — modern, correctly configured.",
"quick_recommendations": ["..."],
"security_assessment": [{ "title": "...", "description": "...", "severity": "info | warning | critical" }],
"fixes": [
{ "issue": "...", "kind": "dns_txt | shell | dig", "host": "...", "snippet": "..." }
]
}
}How teams use DKIM Checker
Six patterns we see most often:
Aggregate reports show mail signed by a selector you don't recognise — but you can't lookup a selector without knowing its name. Our auto-scan surfaces every selector under your domain, revealing services signing on your behalf you didn't know about.
Just rotated to a new selector? Run the scan — you should see both the old and new selector active during the transition, then the old one retired (either removed or `p=` empty).
Google/Yahoo 2024 and Microsoft 2025 bulk-sender rules require DKIM signing. Verify every sending domain grades A before campaigns ship.
Onboarding a new ESP? Check whether your existing DKIM inventory conflicts with their default selector name (rare but happens with Mailchimp `k1` and Klaviyo `dkim`).
Acquiring a company. Multi-selector scan across their sending domains reveals every third-party service they onboarded. Legacy 1024-bit keys signal deferred maintenance.
A phishing campaign is signing as your domain. Header-paste extractor pulls the exact selector from the malicious message so you can verify (a) whether it's actually yours, or (b) an unrelated selector on someone else's key.
Common questions
- Do I need to enter the DKIM selector? No. Leave the selector field blank and we scan ~40 well-known ESP selectors in parallel. If your domain uses any of Google Workspace, Microsoft 365, Mailchimp, SendGrid, Amazon SES, Marketo, HubSpot, Postmark, Mailgun, SparkPost, Salesforce, Zendesk, Klaviyo, Constant Contact, or dozens more, we'll find them. Manual selector input is available for custom / uncommon selector names.
- How is the DKIM grade computed? A = every selector uses ≥2048-bit RSA (or Ed25519), no testing-mode flag, no revoked selectors. B = at least one 1024-bit key. C = at least one selector in testing mode (`t=y`). D = at least one revoked selector (empty `p=`). F = no selectors resolved. Domain grade = worst per-selector grade.
- Why does your key-bit measurement differ from other tools? Most tools report `base64.decode(p=).length * 8` — the raw byte-count of the SPKI blob. For a 2048-bit RSA key that's ~2384 bits. We parse the ASN.1 DER structure to reach the RSA modulus INTEGER and count its actual bit-length. Our number matches what `openssl rsa -pubin -text` reports.
- What is provider detection? Two-tier rule engine. First we match the selector name against a table of known-provider selectors (e.g. `google` → Google Workspace, `k1`–`k3` → Mailchimp, `mte1`/`mte2` → Marketo). If the selector name is generic, we inspect the CNAME chain target — most ESPs delegate to a hostname on their own domain, which lets us identify them anyway.
- What does `t=y` (testing mode) actually do? Tells receivers 'this DKIM setup is under test — accept the signature but don't apply strict enforcement'. Meant to be temporary during initial rollout. Teams add it and forget to remove it, resulting in receivers quietly ignoring the signature, DMARC alignment failing, and mail landing in spam.
- What does an empty `p=` mean? It's the RFC 6376 key-revocation signal. Publishers use it during rotation: publish the new selector first, wait for delivery-log confirmation, then set the old selector's `p=` to empty (rather than removing the record entirely — which would let receivers fall back to cached copies).
- Why do I see the same selector name at multiple providers? Selector names aren't globally unique. `k1` is Mailchimp's default and also a common self-hosted generic. `s1` is SendGrid's default and also generic. We disambiguate via the CNAME target when possible — a CNAME to `*.mailchimpapp.net` is definitive.
- Can I paste an email header to find the selector? Yes — the Diagnostics tab has an email-header paste extractor. Paste the raw `DKIM-Signature:` header from a signed email; we parse `d=` (signing domain) and `s=` (selector) and pre-fill the lookup with them.
- How often should I rotate DKIM keys? Every 6–12 months for high-value domains. Publish a new selector name (e.g. bump `selector1` → `selector2`), configure your MTA to sign with the new key, verify delivery-log signatures for a week, then retire the old selector by emptying its `p=` value. Never rotate under an existing selector name — receivers cache the public key.