# Email DNS Check

> Check a domain's SPF, DKIM, DMARC, MX, BIMI and MTA-STS in your browser: SPF lookup tree with the 10-lookup limit, DMARC policy, key length and plain fixes.

- URL: https://bytescope.dev/en/email-dns-check/
- Locale: en · Also: [ja](https://bytescope.dev/ja/email-dns-check.md) · [zh-Hant](https://bytescope.dev/zh-Hant/email-dns-check.md)
- Runs: Your files never leave your browser — all processing is local.
- Requires: Any modern browser (Chrome, Edge, Firefox, Safari), desktop and mobile.
- Updated: 2026-09-08

## What it does

Most email deliverability problems come down to a handful of DNS records that are easy to get subtly wrong: an SPF record that silently exceeds its lookup limit, a DMARC policy left at `p=none` for years, a DKIM key that was revoked or is too short. This DMARC checker, SPF record checker and DKIM record lookup reads those records straight from your browser. Enter a domain (a full URL or an email address is fine — the page extracts the domain, converts international names to punycode and shows both forms) and optionally the DKIM selectors you use. The page queries the record names — `example.com`, `_dmarc.example.com`, `selector._domainkey.example.com` and so on — through Cloudflare's public DNS-over-HTTPS service, falling back to Google's. That service sees the names and your IP address, as any DNS resolver does; no message is sent, and nothing else about you leaves the browser. The result is a traffic light per card and one overall light: green when the records are correct, yellow when mail will send but something is risky, red when mail is likely to be rejected or the domain is open to spoofing.

### SPF: the 10-lookup limit, explained with a tree

RFC 7208 allows at most ten DNS-querying mechanisms per SPF evaluation — `include`, `a`, `mx`, `ptr`, `exists` and `redirect` all count, and nested includes count too. Exceed it and receivers return `permerror`, which many treat as no SPF at all. The page expands `include:` and `redirect=` recursively into a tree with a lookup marker on every node, so you can see which includes cost the most. `a`, `mx`, `ptr` and `exists` are counted toward the limit but not resolved, because their targets do not change the count. Includes whose target has no record are counted as void lookups, which are limited to two. The page also flags more than one `v=spf1` record (a permerror), `+all` and `?all` (which allow anyone), the deprecated `ptr` mechanism, syntax errors and include loops — a loop is only a domain that appears in its own ancestor path; the same include referenced from two branches is legitimate and is counted twice, as receivers count it. When you are over the limit, the fix offered is to remove includes for services you no longer use or to move a sending service to its own subdomain. SPF flattening — replacing includes with the IP addresses they resolve to today — is deliberately not offered: those addresses change without notice, and a flattened record breaks the day your email provider changes its ranges.

### DMARC: from p=none to a policy that protects you

The page fetches `_dmarc.<domain>` and, when a subdomain has no record of its own, falls back to the organisational domain as RFC 7489 specifies, using the Public Suffix List to find it. It reports the policy (`p=`), the subdomain policy (`sp=`), `pct=`, the alignment modes `adkim=` and `aspf=`, and the reporting addresses `rua=` and `ruf=`. `p=none` is marked as monitoring only: receivers report but do not act, so the domain is still spoofable; `pct` below 100 means only a share of failing mail is acted on. When `rua=` points at a mailbox in another domain, the page looks for the authorisation record `<domain>._report._dmarc.<report domain>` and warns that reports will not be sent if it is missing. The suggested path is the one that does not break mail: start with `p=none; rua=mailto:…`, read the reports until every legitimate sender is aligned, then move to `quarantine` and finally `reject`.

### DKIM, MX, BIMI, MTA-STS and TLS-RPT

DKIM selectors cannot be enumerated from outside — DNS has no way to list `*._domainkey` names — so the page tries the selectors you enter plus a list of common names (`google`, `selector1`, `selector2`, `k1`, `s1`, `s2`, `default`, `dkim`, `mail` and others). Not found therefore means not found under these names, never that DKIM is unconfigured. Keys that are found are checked for length (RSA under 1024 bits is red, 1024 is yellow), for an empty `p=` meaning the key was revoked, for `t=y` test mode and for syntax. MX records are listed by priority with their addresses; a missing MX is flagged, an MX pointing at a CNAME is flagged, and a Null MX (`0 .`, RFC 7505) is reported as the correct way to say a domain does not receive mail, not as an error. BIMI (`default._bimi`) is checked for format and shown with its `l=` logo and `a=` certificate URLs; the logo itself is not fetched, and the card reminds you that BIMI only takes effect under a DMARC policy of `quarantine` or `reject`. MTA-STS (RFC 8461) and TLS-RPT (RFC 8460) are checked at the DNS level only: a browser cannot fetch `https://mta-sts.<domain>/.well-known/mta-sts.txt` because of CORS, so the policy URL is shown as a link for you to open.

### What a green light means — and what it does not

The records shown are what Cloudflare's or Google's resolver sees right now. A record you changed minutes ago may still be cached for its TTL, so re-check after it expires rather than assuming the change failed. Green means the records are correctly set, not that your mail will reach the inbox: sender reputation, content and sending volume decide that, and none of it is visible from DNS. For the same reason there is no numeric score — a number like 87 would look precise while meaning nothing. If a particular message bounced or landed in spam, open its headers in the email header analyzer, which traces the route and verifies DKIM; its summary card links back here with the sender's domain. Both pages produce a Markdown report and a JSON export you can paste into a ticket.

## Limits

Does not send test mail, flatten SPF or fetch MTA-STS policy files and BIMI logos; it checks the DNS records only.

## FAQ

### My SPF record has too many DNS lookups. How do I fix it?

Look at the SPF tree: every `include`, `a`, `mx`, `ptr`, `exists` and `redirect` costs one lookup, nested includes included, and the limit is ten. First delete includes for services you no longer send through — old newsletter tools and CRMs are the usual culprits. If you still exceed ten, move one sending service to its own subdomain with its own SPF record, for example `news.example.com` for the newsletter platform. Do not flatten the record into IP addresses: providers change their ranges without notice, and a flattened record breaks silently when they do.

### Is DMARC p=none enough?

As a starting point, yes; as a destination, no. With `p=none` receivers only send you reports — they still deliver mail that fails authentication, so anyone can send mail as your domain and most receivers will accept it. Use the `p=none` phase to read the `rua=` reports and find legitimate senders that are not yet aligned, then move to `p=quarantine` and finally `p=reject`. BIMI logos also require `quarantine` or `reject`. The page marks `p=none` as monitoring only for exactly this reason.

### The DKIM check says not found. Does that mean DKIM is not set up?

No. DKIM records live at `<selector>._domainkey.<domain>`, and DNS offers no way to list selectors, so the page can only try the names you give it plus a list of common ones. If your provider uses a selector that is not on that list, enter it — it is in your provider's DKIM setup page, or in the `s=` tag of the `DKIM-Signature` header of any message you sent, which the email header analyzer displays. Not found means not found under the tried names, nothing more.

### I just changed a record, but the check still shows the old one.

DNS answers are cached for the record's TTL, and the page reads what Cloudflare's resolver (or Google's, as fallback) currently holds. A record you edited a few minutes ago can still be served from cache for as long as its TTL — often an hour, sometimes a day. Wait for the TTL to pass and check again.

### Everything is green, so why do my emails still go to spam?

Because correct records are necessary but not sufficient. Receivers also weigh the reputation of your domain and sending IPs, the content of the message, how recipients react to it, and sudden changes in sending volume — none of which is visible from DNS, which is why this page shows no deliverability score. Start from a specific message that went to spam: open its headers in the email header analyzer to see which checks the receiving server actually ran, whether DKIM aligned with the `From` domain, and what its spam-filter headers say.

### Why is there no score?

Because a number would be false precision. Checks have different weights for different domains — a missing MX is fatal for a domain that receives mail and correct for one that does not, and `p=none` is a sensible first step for a domain rolling out DMARC but a gap for one that has been sending for years. The page gives one light per card and an overall light instead: green, yellow for mail that sends but carries a risk, red for mail that is likely to be rejected or a domain that is open to spoofing. Each card then says what to change.

### What leaves my browser when I run a check?

DNS queries for the record names of the domain you entered — the domain itself, `_dmarc.`, `_domainkey.`, `_bimi.`, `_mta-sts.` and `_smtp._tls.` names — sent to Cloudflare's DNS-over-HTTPS service, with Google's as fallback if Cloudflare fails. Those services see the names and your IP address, which is how every DNS query works. The domain name is public information; no message, no address book and nothing else is sent. The analytics event records that a check ran, never the domain.

### Does a domain that never receives mail need MX records?

It should publish a Null MX: a single MX record with priority 0 and the target `.` (RFC 7505). That tells senders the domain does not accept mail, so they fail fast instead of retrying against the address records for days. The page reports a Null MX as correct configuration, not as a missing MX. Such a domain still benefits from `v=spf1 -all` and a DMARC record with `p=reject`, so nobody can send mail pretending to be it.

## Related tools

- [Email Header Analyzer](https://bytescope.dev/en/email-header-analyzer.md) — Paste a message's headers to see its route and verify DKIM →
- [EML Viewer](https://bytescope.dev/en/eml-viewer.md) — Open an .eml file and read it safely →
- [MSG Viewer](https://bytescope.dev/en/msg-viewer.md) — Open an Outlook .msg file without Outlook →
- [Certificate Decoder](https://bytescope.dev/en/certificate-decoder.md) — Decode a TLS certificate and check its dates →
