Email deliverability checker.

Check SPF, DKIM, DMARC and MX for a domain in one pass. Everything a receiving mail server looks at before deciding whether your message is real: who may send for the domain, whether messages are signed, what to do when they are not, and whether the mail servers themselves speak TLS. Each finding is explained, not just flagged.

About this tool

Every check is a live DNS query from this server (via Cloudflare's resolver) plus a short connection to each mail server on port 25 to see whether it offers STARTTLS and what certificate it presents. Nothing is sent and no mail is involved; the SMTP session stops after EHLO and STARTTLS. Only public domains can be checked and nothing is stored. For the email findings alongside DNS, certificate and HTTP in one graded report, run the domain health checker.

MX lookup and STARTTLS

The mail servers for the domain in preference order, the addresses they resolve to, and whether each answers on port 25. For each one that does, the probe sends EHLO, asks for STARTTLS and records the TLS version negotiated and whether the certificate is valid for the MX hostname. A refused STARTTLS means mail to you crosses the internet in the clear; a certificate for the wrong name means senders that enforce MTA-STS will not deliver. A domain that publishes a single null MX (0 .) is saying it does not receive mail, and is graded on that basis.

SPF checker

The v=spf1 record is parsed into a tree so you can see what every include pulls in, with the DNS-querying mechanisms (include, a, mx, ptr, exists, redirect) counted against the limit of ten exactly as a receiver counts them, and the all qualifier at the end. The count is the thing to watch: one SaaS provider's include can silently bring three or four lookups with it, and at eleven the whole record is a PermError and receivers ignore it. Two SPF records is the other way to get there. See the SPF 10 lookup limit and SPF PermError.

Three things the tree shows that a plain count misses. An include reached twice through two different providers is counted twice, because receivers evaluate it twice; the second copy is marked. A lookup that returns nothing (an include of a name that does not exist or has no TXT, an mx term on a domain with no MX) is a void lookup, and RFC 7208 allows two of those before the record is a PermError in its own right. And when an include target is a CNAME, the chain is shown, so a record that "vanished" because the provider aliased the name to something with no TXT is explained rather than just red. Each mx term is resolved to count its hosts against the separate limit of ten, a redirect that sits next to an all is marked as ignored, and unknown mechanisms and malformed ip4/ip6 terms are called out as the PermError they are. The JSON output carries all of this: lookups, void_lookups, via_cname, duplicate and a flat spf_problems list.

DKIM checker

Public keys found under common selectors (google, selector1, selector2, k1, default and others), the key type and length, and flags such as testing mode (t=y) or a revoked key (empty p=). Selectors are chosen by the sender, so a custom one cannot be guessed here; find it in the DKIM-Signature header of a message the service sent (s=) and check it with a DNS TXT lookup on selector._domainkey.domain. Keys under 2048 bits still verify but are increasingly flagged.

DMARC checker

The _dmarc record decoded: the policy (p=), the subdomain policy, the percentage it applies to, the SPF and DKIM alignment modes and where aggregate and forensic reports go. Policy is what receivers act on: none monitors, quarantine sends failures to spam, reject refuses them. A record with p=none and no rua address is collecting nothing and enforcing nothing. See DMARC none vs quarantine vs reject and, for how the three mechanisms depend on each other, SPF vs DKIM vs DMARC.

MTA-STS, TLS-RPT and BIMI

Whether the domain tells large senders to insist on TLS: the _mta-sts record and the policy file at https://mta-sts.domain/.well-known/mta-sts.txt, fetched the way a sender fetches it (no redirects followed) and checked line by line: version, mode, max_age, the mx patterns, the id format and the content type. The mx lines are then matched against the real MX hosts with the RFC 8461 wildcard rule, and each host is shown as covered or not. In enforce mode an uncovered host, a host that refuses STARTTLS, or a certificate that does not verify for the MX name is graded as a fail, because that is what Gmail and Outlook.com do with it: they stop delivering to that host. max_age is written out as a duration, since it is the length of time a sender keeps applying the policy it has cached if the id is not changed or the policy host is down, which is how an MX migration turns into a week of bounces. See MTA-STS explained and max_age and the policy cache. The block also shows where TLS failure reports are sent (_smtp._tls), and whether a brand logo record is published and the DMARC policy is strict enough for it to be honoured.

How SPF, DKIM and DMARC fit together

SPF says which servers may send mail for the domain. Over ten DNS lookups and the whole record is ignored, which is the most common reason SPF "stops working" after adding a new SaaS provider. DKIM signs each message with a private key whose public half is published under a selector; the selector name is chosen by the sender. DMARC ties the two together: it tells receivers what to do when a message fails both and where to send reports. Without DMARC, SPF and DKIM are advisory. MTA-STS and TLS-RPT harden the connection itself: STARTTLS on its own can be stripped by anyone in the path, and MTA-STS lets you tell big senders to refuse unencrypted delivery.

Common email deliverability problems

Examples

From the command line

curl "kirkdiamond.com/tools/mail?domain=example.com" or add &format=json. Useful for working out why mail lands in spam, checking a new provider's records before switching, confirming the last step to p=reject is safe, and auditing a domain you are about to send on behalf of.

Every parameter, the JSON field names, rate limits and ready-made CI checks are in the API and curl reference.