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 github.com via 1.1.1.1 · 1.246s JSON · text

Overall Grade B 3 pass · 2 warn · 0 fail
SPF 10 / 10 lookups ends in ~all
DMARC p=quarantine reports to mailto:[email protected]
DKIM 10 keys cm, google, k1, k2, k3, s1, s2, selector1, zendesk1, zendesk2

Findings

Mail servers MX · port 25 probed from this server

PrefHostAddressSTARTTLSCertificate
0 github-com.mail.protection.outlook.com 52.101.41.125, 52.101.9.93, 52.101.42.14, 52.101.8.35, 2a01:111:f403:c902::1, 2a01:111:f403:c803::, 2a01:111:f403:f90a::4, 2a01:111:f403:f804::3 TLS 1.3 150ms valid

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

github.com10 lookups below
  • ip4:192.30.252.0/22
  • include:spf.protection.outlook.com lookup
    spf.protection.outlook.com0 lookups below
    • ip4:40.92.0.0/15
    • ip4:40.107.0.0/16
    • ip4:52.100.0.0/15
    • ip4:52.102.0.0/16
    • ip4:52.103.0.0/17
    • ip4:104.47.0.0/17
    • ip6:2a01:111:f400::/48
    • ip6:2a01:111:f403::/49
    • ip6:2a01:111:f403:8000::/51
    • ip6:2a01:111:f403:c000::/51
    • ip6:2a01:111:f403:f000::/52
    • -all hard fail: anything else is rejected
  • include:_netblocks.google.com lookup
    _netblocks.google.com0 lookups below
    • ip4:74.125.0.0/16
    • ip4:209.85.128.0/17
    • ~all soft fail: unlisted senders are marked, not rejected
  • include:_netblocks2.google.com lookup
    _netblocks2.google.com0 lookups below
    • ip6:2001:4860:4000::/36
    • ip6:2404:6800:4000::/36
    • ip6:2607:f8b0:4000::/36
    • ip6:2800:3f0:4000::/36
    • ip6:2a00:1450:4000::/36
    • ip6:2c0f:fb50:4000::/36
    • ~all soft fail: unlisted senders are marked, not rejected
  • include:mail.zendesk.com lookup
    mail.zendesk.com0 lookups below
    • ip4:103.151.192.0/23
    • ip4:185.12.80.0/22
    • ip4:188.172.128.0/20
    • ip4:192.161.144.0/20
    • ip4:216.198.0.0/18
    • ~all soft fail: unlisted senders are marked, not rejected
  • include:_spf.salesforce.com lookup
    _spf.salesforce.com1 lookup below
    • exists:%{i}._spf.mta.salesforce.com lookup macro: expanded per message, so the target cannot be checked here
    • -all hard fail: anything else is rejected
  • include:servers.mcsv.net lookup
    servers.mcsv.net0 lookups below
    • ip4:205.201.128.0/20
    • ip4:198.2.128.0/18
    • ip4:148.105.0.0/16
    • -all hard fail: anything else is rejected
  • include:mktomail.com lookup
    mktomail.com0 lookups below
    • ip4:199.15.212.0/22
    • ip4:72.3.185.0/24
    • ip4:72.32.154.0/24
    • ip4:72.32.217.0/24
    • ip4:72.32.243.0/24
    • ip4:94.236.119.0/26
    • ip4:37.188.97.188/32
    • ip4:185.28.196.0/22
    • ip4:192.28.128.0/18
    • ip4:103.237.104.0/22
    • ip4:130.248.172.0/24
    • ip4:130.248.173.0/24
    • ~all soft fail: unlisted senders are marked, not rejected
  • include:sendgrid.net lookup
    sendgrid.net1 lookup below
    • ip4:167.89.0.0/17
    • ip4:208.117.48.0/20
    • ip4:50.31.32.0/19
    • ip4:198.37.144.0/20
    • ip4:198.21.0.0/21
    • ip4:192.254.112.0/20
    • ip4:168.245.0.0/17
    • ip4:149.72.0.0/16
    • ip4:159.183.0.0/16
    • ip4:134.128.64.0/18
    • ip4:159.26.176.0/20
    • include:ab.sendgrid.net lookup
      ab.sendgrid.net0 lookups below
      • ip4:223.165.113.0/24
      • ip4:223.165.115.0/24
      • ip4:223.165.118.0/23
      • ip4:223.165.120.0/23
      • ~all soft fail: unlisted senders are marked, not rejected
    • ~all soft fail: unlisted senders are marked, not rejected
  • ip4:62.253.227.114
  • ip4:166.78.69.169
  • ip4:166.78.69.170
  • ip4:166.78.71.131
  • ~all soft fail: unlisted senders are marked, not rejected

DMARC _dmarc.github.com

v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1
Policy
quarantine (mail that fails both SPF and DKIM alignment is sent to spam)
Subdomains
reject
Applies to
100% of failing mail
Alignment
DKIM relaxed, SPF relaxed
Aggregate
mailto:[email protected]
Forensic
mailto:[email protected]

DKIM keys found by probing common selectors

SelectorKeyFlagsRecord
cm rsa 1024 bit weak k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXLybkpDQnCyQYlQc46kL2sPMsYDqwkjPyFRSDiaq6qUeujAlU775+f8rzxIrjHc8sPstAZOuJzqcgDPiidRxdE2Th/lcnfbN4btWvJwHKK6KD/IazNWNqQtunYyPzfmSRTtOE4Nii4Oxwx1glTJAVhCTObD2uh2U44lCG+pgYswIDAQAB
google rsa 2048 bit v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6T5sl/RwdSqGoYWaWaFbS2UAeyPrEmd0gogocmRfS441qwR8/0KB81Hw89P0l4YiFRrXYk7NVIGfyCRHAYYZUzCkGeOysI2EjgzLFhd/NEsbRzOEc/kWkK/RO6JFq/5lOn6M9AZw/ap9tds4JG9ApgNNdSpPxp9DmvpsOSgNMVflRxQFrk3kdS4RNAPKu/OPoA7dlR/A/pECryjRoYgENtDXzdnK70HgCekems6UDzxDj61cjyoKoXtEMF/QsaHEQ1Gjfv014rDJBsubk/kT5VqHkWHa/ia68Z5r228Ety/wFfQNjXTx/J7KGZ9GkZlKED659eiJcLnWcKDSiQlhwIDAQAB
k1 rsa 1024 bit weak k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbNrX2cY/GUKIFx2G/1I00ftdAj713WP9AQ1xir85i89sA2guU0ta4UX1Xzm06XIU6iBP41VwmPwBGRNofhBVR+e6WHUoNyIR4Bn84LVcfZE20rmDeXQblIupNWBqLXM1Q+VieI/eZu/7k9/vOkLSaQQdml4Cv8lb3PcnluMVIhQIDAQAB;
k2 rsa 2048 bit v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2aC2KjGKLOwTweBY5A9RpjsxaBXR9r7OAU6U8/zn92ivImI75naUujWbItRI/QmL1jy5PWGqLwoUA0b90ObWaLDc+i9MtTNmGeWO009hr20fIxhGg6XBT2kjZ1DTThopSe1nAndsupmcBwlQ5Q6LJ+ZAxLcujnPIxM0ZBLmgpkv8u6RfY4eFP8OLvdAW3oSuB0DyLDigQX4Sj8wBO4YIdQH6AAmBeOsidsKAFNFUCpc3vCxtBDR12U+cBg724l3sBkMQ8evnz6idnqxq9QAVYh8k4kJ+RP+6cqTdy7LjIm8xY/bQNpQIpGUAuDo2DjLcCDun9DAI4Q/3z+Q0o9QuQIDAQAB;
k3 rsa 2048 bit v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsYGiMSn7fsUqSvfSX40x9R1OlRtbNiCY80lHRIlcKx3XDIR7257aUx+q9CSIARdfTL6KCuLGNFx5g9TgVr6png4ajcieSQGtOehBgxnkDN8aAA5TX0FmFrcefJU0JoxLOF09EKgXxhSSHCk/ekVb0PXSboHXoZ9+EI404F1qhcwXXIgHXTaUthHTut2P6BBZhIXIgvDe/w49GchR7MRJqjNb7neEBbYHbgWuBTvvHCg7Gy6m6n9krYK+ROWq3dVvXy9plAGK3ygM+HtjIiMt7arRGMOF0WgDTz7YdN9BGpt6BvXxLnjiQcgS5T9n+cIyPZgiWzDMXNlaEEdKTEKxrwIDAQAB;
s1 rsa 2048 bit k=rsa; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn3fMCVpb7ryIRKOGXhXVGYmsWUitNlSckqGHOwNFZgFadplOrD+Qzf1XQkP7MH/VB/97DsAAJGtEXW1Uq71Hjnfr/DuBN/YfjF/gU70qEFb7q1sdIiNtjFL2TkOpoW+X/bhhPNheW/fYwyFb6ZHFM6LTgXyuimWRHTOUP3VjZzhNVda79nt+2WZYbS4l8HdMgWpTNHjpVw5PtXESA9KBg/evSRk5fIaXIX5eRXW3baoV9yVzD8O29/IL/DiSk+yNvaO0EHL5c4yGuZJhGzvpiznb2IDVdemJK4Dqzdy5FTN/SGYZhAEr7MguG3Z314hMS2scgMsOMgB64uj/6+6UwIDAQAB
s2 rsa 2048 bit k=rsa; t=s; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNt2/H6bKs99C6DAaokPp62KN9mKaD20D1PBakkObejkJvzM6Un/fKHPeI2/qXdvFFBPQE3mxMNoe+hwBVDgMgCuZEn8J6gZYI4amITure9/ny6+GaNVRoH2m6xAtWwKINkKxMayGiehkWlRVb7D23F0U8y+VDHKQFz1bnXA5jDpcDiMXy8i2lV5vEys+qt+1WGhDKCAwamT8c3xkZz8aXMJaXYCiN2HMgHDU81+mVCk4+u6mY+a98APVfFhsQ0KCq/mVZXaXTV06QrG9M5PtBHUFW7VtwXKp+AFrAut0KW1NnwaA5IGA5sc+n9dma7bSqdfGS+ixdSmJ69NwmYSHwIDAQAB
selector1 rsa 1024 bit weak v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxZC/z2cK+2s1f/ktzSDSeFzkfIHrjwtGFsfKMAYvKaXjPVNzKykpbXBkX5nB7dVUTFttda7aROr2iSrIseQ27Ui+4rUZVzgFanE8RaXhYM9n5wPKNv8GtLJk7JgcsYZ7ErgID4uW2sEYyV/dnRYw6rDzOaeRKkKELTUfJI5ebLQIDAQAB;
zendesk1 rsa 2048 bit v=DKIM1;t=s;n=core;k=rsa;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9IqdLrO3Zr2/56MHt8oQVCQorP0Bl2Fz9sM2tFBnJCdB/HogQmuudEg2xAovCN2PYpw44UijIvPuBoT9vxiv6ZCBJTLJXa82r6ke5rE4tbe9NKFIrVIb9S306cJDrnKFMDb8p0dU/Su0+eUR5gVAOtCuz2L8HAzs5edvsEvD/Fb4ny1RLNSEPZkIQLfGhVxQeWANm3+1Jwb/OBVXV9k0nKpWrpgqcmO7NzroJirp014RQY7rGi60JLUubc6XhvoFQBQrtOAdVlZC5wvfS1bgpq5kQpdP7cajIqWCeqxPTeo0ZUpey2ZcaygEsZz0Z3Gs5wDzyuqd7/ADpr2jNF7ozwIDAQAB
zendesk2 rsa 2048 bit v=DKIM1; t=s; n=core; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmiSFNkgXrO3I8aOaPONDZWHv027rkiGIwb838OyXPgvFDEkCV/qGcdXSjZnaVAadrTm/oKnL8WOltP9zB1FLEuKt0fTi5zRyKPE4oIYCnEzXwrGqzjUcCABQBawQVqvXjDOaYh9Lhp8W5PYOLo905vRW7ipyIMDhuzBOJls91/WWXnNK0OwP3RghiisZjA3K2KqtRwf7w6GjNeNuAMNhvcmgAN15d/mhK+dev/hcRbal66RoYyTD8c0F0isahWH0envEX8aj+SBhheNk0/U37dGE+4nFaY5yP9CUlYjFKDSIKZgHzG4Hci3t/RubU58pi6BCrQQdAFvIOeDFeCZ0ywIDAQAB

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.