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.

Checked gmail.com via 1.1.1.1 · 631ms JSON · text

Overall Grade B 5 pass · 1 warn · 0 fail
SPF 1 / 10 lookups ends in ~all
DMARC p=none reports to mailto:[email protected]
DKIM Not found none of 43 common selectors

Findings

  • pass
    MX records 5 gmail-smtp-in.l.google.com, 10 alt1.gmail-smtp-in.l.google.com, 20 alt2.gmail-smtp-in.l.google.com, 30 alt3.gmail-smtp-in.l.google.com, 40 alt4.gmail-smtp-in.l.google.com

    Inbound mail is routed to these hosts, lowest preference first.

  • pass
    STARTTLS 5 of 5 offer TLS with a valid certificate

    Inbound mail can be encrypted in transit.

  • pass
    SPF ~all, 1 of 10 lookups

    Soft fail. Unlisted senders are flagged rather than rejected; with DMARC in place that is enough for alignment. -all is stricter once you are confident every sender is listed.

  • warn
    DMARC p=none

    Monitoring only. Spoofed mail is still delivered; you just get told about it. Once the reports show all legitimate senders passing, move to p=quarantine and then p=reject.

    Why this matters: DMARC p=none vs quarantine vs reject: which policy to use and when to move

  • info
    DKIM no common selectors found

    Checked 43 selectors used by common providers. DKIM keys live at <selector>._domainkey and the selector name is chosen by the sender, so a custom one cannot be discovered from outside. Check a real message's DKIM-Signature header for the s= value.

    Why this matters: SPF vs DKIM vs DMARC: what each one proves and why you need all three

  • pass
    MTA-STS mode: enforce

    Senders that support MTA-STS will refuse to deliver over an insecure connection. The policy covers all 5 MX hosts and is cached for 1 day; change the id when you change it.

  • pass
    TLS-RPT v=TLSRPTv1;rua=mailto:[email protected]

    Senders will report TLS delivery problems to this address.

Mail servers MX · port 25 probed from this server

PrefHostAddressSTARTTLSCertificate
5 gmail-smtp-in.l.google.com 192.178.223.27, 2a00:1450:4009:c0f::1a TLS 1.3 12ms valid
10 alt1.gmail-smtp-in.l.google.com 142.250.102.26, 2a00:1450:4025:402::1a TLS 1.3 16ms valid
20 alt2.gmail-smtp-in.l.google.com 192.178.213.26, 2a00:1450:4013:c1e::1b TLS 1.3 21ms valid
30 alt3.gmail-smtp-in.l.google.com 142.251.127.27, 2a00:1450:4001:c21::1b TLS 1.3 23ms valid
40 alt4.gmail-smtp-in.l.google.com 192.178.228.27, 2a00:1450:4025:4403::1a TLS 1.3 32ms valid

SPF tree 1 of 10 DNS lookups used · 0 of 2 void

gmail.com1 lookup below
  • redirect=_spf.google.com lookup
    _spf.google.com0 lookups below
    • ip4:74.125.0.0/16
    • ip4:209.85.128.0/17
    • ip6:2001:4860:4864::/56
    • ip6:2404:6800:4864::/56
    • ip6:2607:f8b0:4864::/56
    • ip6:2800:3f0:4864::/56
    • ip6:2a00:1450:4864::/56
    • ip6:2c0f:fb50:4864::/56
    • ~all soft fail: unlisted senders are marked, not rejected

DMARC _dmarc.gmail.com

v=DMARC1; p=none; sp=quarantine; rua=mailto:[email protected]
Policy
none (mail that fails both SPF and DKIM alignment is delivered anyway)
Subdomains
quarantine
Applies to
100% of failing mail
Alignment
DKIM relaxed, SPF relaxed
Aggregate
mailto:[email protected]

Transport policy mode: enforce · cached up to 1 day

MTA-STS
v=STSv1; id=20190429T010101;
Policy file
version: STSv1
mode: enforce
mx: smtp.google.com
mx: gmail-smtp-in.l.google.com
mx: *.gmail-smtp-in.l.google.com
max_age: 86400
MX coverage
gmail-smtp-in.l.google.com alt1.gmail-smtp-in.l.google.com alt2.gmail-smtp-in.l.google.com alt3.gmail-smtp-in.l.google.com alt4.gmail-smtp-in.l.google.com
Cache
max_age 86400 (1 day). A sender that has fetched this keeps applying it that long unless the id changes; change the id every time you change the file.
TLS-RPT
v=TLSRPTv1;rua=mailto:[email protected]

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.