Email authentication

Zoho Mail setup checker

Confirm the SPF include Zoho documents, the zoho DKIM selector and Zoho’s mail hosts for a domain.

Free, no accountLive check

Try

Result

The verdict appears here once you press Check Zoho Mail records.

What this is

This zoho mail setup checker confirms the parts of a Zoho Mail setup that are the same for every account - the SPF include and the three mail hosts - and is honest about the one part that is not, the DKIM selector an admin types into Zoho’s own console.

Zoho’s SPF page documents two includes and no others: include:zohomail.com for Zoho Mail, and include:one.zoho.com where several Zoho services send as the same domain. Both read the same for every account, which is what makes them checkable from outside - unlike the DKIM key, which is generated behind a login.

DKIM is where a Zoho setup check has to stop being strict. Zoho asks for a selector name when the key is created and uses “zoho” as the example on its own page, so that is the name tried here. A domain signing under some other name is indistinguishable in DNS from one not signing at all, so this page names what it tried and where the real name is written down.

How to read the result

The SPF line comes back one of three ways: the include Zoho documents, an include Zoho no longer documents, or no mention of Zoho anywhere. Each carries what to publish, and it goes inside the SPF record already on the domain rather than beside it as a second one.

The lookup figure is this domain’s own: the number of DNS lookups its published SPF chain actually walked, counted by the same walk the SPF checker runs, with whatever is left of the ten RFC 7208 allows. It is measured, not quoted from a table of averages.

This checker only covers Zoho Mail’s own fixed SPF includes; DKIM is checked at Zoho’s example selector, which is chosen per account. For how SPF, DKIM and DMARC fit together, what order to fix them in, and what to do once one fails, see our guide How SPF, DKIM and DMARC work together, and what to do when one fails.

Common mistakes

What goes wrong most often, and how to tell.

  • Publishing include:zoho.com because an older guide said toZoho’s SPF page documents zohomail.com and one.zoho.com, and nothing else. An include missing from the vendor’s current documentation may resolve perfectly today and is a poor thing to leave a domain’s authentication resting on, since nothing will announce the day it narrows.
  • Reading a missing zoho selector as proof DKIM is switched offThe selector is whatever was typed into the console when the key was generated, and DNS publishes no list of the selectors a domain uses. The only reliable place to read the name is the Email Authentication page of the Zoho Mail admin console itself.
  • Counting the ten-lookup limit per include instead of per domainRFC 7208 allows ten lookups for the whole chain a receiver has to walk for one message, not ten for each include inside it. Adding one more sending service to a record already close to the ceiling is what turns every SPF check for that domain into a permanent error.
  • Publishing both Zoho includes to be safeThey are alternatives, not a pair: one.zoho.com is the one Zoho recommends where several of its services send as the domain. Listing both spends an extra DNS lookup from the ten available and authorises nothing that the right single include does not already cover.

Questions

What people ask about this tool.

  • Zoho’s own page documents include:zohomail.com for Zoho Mail, and include:one.zoho.com where several Zoho services send as the same domain. Either is correct on its own, and publishing both in one record spends a DNS lookup for nothing.
  • It is not on Zoho’s SPF page any more, which is the whole problem: a value a vendor has stopped documenting can be changed or withdrawn without any notice reaching the domains depending on it. This check flags it so it can be swapped for the include Zoho publishes today.
  • No. Zoho has the admin choose the selector name in the console when the key pair is generated, and “zoho” is only the example its documentation shows. This page tries that one name, so a domain signing under another is reported as nothing found there, not as broken.
  • The result states the count this domain’s chain actually walked and what remains of the ten RFC 7208 allows, worked out by following the record’s own includes rather than assuming a fixed cost for Zoho’s include.

Sources

Every fixed value here comes from the provider’s own documentation. These pages change, so each says the day it was last read.

Use it from the API

The same check, as one request.

Request
curl -X POST https://resellerhq.com/api/tools/zoho-mail-setup-checker \
  -H "Content-Type: application/json" \
  -d '{"domain":"zdocs.example"}'
Response
{
  "tool": "zoho-mail-setup-checker",
  "input": {
    "domain": "zdocs.example"
  },
  "result": {
    "verdict": {
      "tone": "success",
      "headline": "Zoho Mail on zdocs.example matches what Zoho documents",
      "summary": "The SPF include and mail hosts are compared with Zoho's own pages; DKIM is tried at the \"zoho\" selector those pages use as their example."
    },
    "findings": [
      {
        "id": "zoho-spf-lookup-budget",
        "severity": "info",
        "title": "1 of the 10 SPF lookups spent",
        "detail": "Walking the SPF record at zdocs.example cost 1 DNS lookup, which leaves 9 of the 10 RFC 7208 §4.6.4 allows for every other service that sends as this domain. That is the count for this chain as published, measured include by include."
      },
      {
        "id": "zoho-dkim-selector-found",
        "severity": "info",
        "title": "A key is published at zoho._domainkey",
        "detail": "zoho._domainkey.zdocs.example holds a key, and \"zoho\" is the selector name Zoho's own DKIM page uses in its example. The name is chosen in the Zoho admin console when the key is generated, so finding one here means this domain kept that example name."
      },
      {
        "id": "dkim-key-type-recognised",
        "severity": "info",
        "title": "DKIM: 2048-bit RSA key",
        "detail": "The modulus decoded from \"p=\" is 2048 bits, read directly from the DER-encoded key rather than estimated from its length."
      },
      {
        "id": "zoho-mx-documented-hosts",
        "severity": "pass",
        "title": "All three Zoho mail hosts are published",
        "detail": "zdocs.example delivers to 10 mx.zoho.com, 20 mx2.zoho.com, 50 mx3.zoho.com - the set Zoho documents for its global service, in that order of priority."
      },
      {
        "id": "zoho-spf-include-found",
        "severity": "pass",
        "title": "SPF includes zohomail.com, as Zoho documents",
        "detail": "The SPF record at zdocs.example includes zohomail.com, which Zoho's own SPF page documents for Zoho Mail. Either of its two includes is correct on its own; both together only cost a lookup."
      },
      {
        "id": "spf-spf-record-found",
        "severity": "pass",
        "title": "SPF: SPF record found",
        "detail": "zdocs.example publishes \"v=spf1 include:zohomail.com -all\", using 1 of the 10 DNS lookups RFC 7208 §4.6.4 allows."
      },
      {
        "id": "spf-hardfail-all",
        "severity": "pass",
        "title": "SPF: \"-all\" hard-fails unlisted senders",
        "detail": "Anything not explicitly listed in this record fails SPF outright, which is what a finished record should say once every real sending server is accounted for."
      },
      {
        "id": "dkim-dkim-record-found",
        "severity": "pass",
        "title": "DKIM: DKIM key published at selector \"zoho\"",
        "detail": "zoho._domainkey.zdocs.example publishes a rsa key."
      },
      {
        "id": "dmarc-dmarc-record-found",
        "severity": "pass",
        "title": "DMARC: DMARC record found",
        "detail": "_dmarc.zdocs.example publishes \"v=DMARC1; p=reject; rua=mailto:[email protected]\". A receiver that honours this rejects failing mail outright."
      }
    ],
    "parts": [
      {
        "kind": "table",
        "title": "What Zoho documents, against what is published",
        "columns": [
          "Record",
          "Zoho documents",
          "Published"
        ],
        "rows": [
          [
            "MX",
            "10 mx.zoho.com, 20 mx2.zoho.com, 50 mx3.zoho.com",
            "10 mx.zoho.com, 20 mx2.zoho.com, 50 mx3.zoho.com"
          ],
          [
            "TXT (SPF)",
            "include:zohomail.com or include:one.zoho.com",
            "v=spf1 include:zohomail.com -all"
          ],
          [
            "TXT (DKIM)",
            "zoho._domainkey, as the page's example",
            "a key at zoho._domainkey"
          ]
        ],
        "mono": [
          1
        ],
        "note": "The DKIM row is the one Zoho does not fix for every account: the selector is whatever was typed into the admin console, so only that one name can be tried from outside."
      }
    ],
    "lookups": [
      {
        "label": "MX for zdocs.example",
        "value": "Cloudflare: 3 records"
      },
      {
        "label": "TXT for zdocs.example",
        "value": "Cloudflare: 1 record"
      },
      {
        "label": "TXT for zohomail.com",
        "value": "Cloudflare: 1 record"
      },
      {
        "label": "TXT for zoho._domainkey.zdocs.example",
        "value": "Cloudflare: 1 record"
      },
      {
        "label": "TXT for _dmarc.zdocs.example",
        "value": "Cloudflare: 1 record"
      }
    ],
    "limits": [
      "The key Zoho shows under Email Authentication in its own control panel cannot be compared with the one published here - only the live DNS side is visible from outside, so a key rotated in the console and never republished looks entirely correct.",
      "Only the \"zoho\" selector is tried, because that is the one Zoho's documentation uses as its example. A domain signing under a name an admin chose cannot be found from DNS at all, since nothing lists a domain's selectors.",
      "Zoho runs regional services whose mail hosts and includes differ from the global ones named here, so records pointing at one of those are reported rather than judged."
    ]
  }
}

This example uses a name RFC 2606 reserves for documentation, ending in .example, .test, .invalid or .localhost. None of them is a real domain, and nobody can register one.

Resell mailbox licences for the domains you just checked, under your own brand.

Get started

Company names and logos are trademarks of their owners, shown only to identify each service.