MCP documentation menu

Domain Health Probe

datapulse_live_domain_health runs a live technical health check of one domain and returns the full report: DNSSEC-validated DNS records, DNSSEC state, delegation consistency, a nameserver audit, TCP 80/443 reachability, the TLS chain and certificate served on 443, one HTTP request per port with HSTS (redirects are not followed: the chain a browser follows is the scrape’s redirect_chain), QUIC/HTTP3 on every address, mail posture (DMARC, SPF, MX, DKIM, MTA-STS, TLS-RPT), CAA, DANE/TLSA, wildcard detection and reserved-address checks. It is always synchronous and always live — every call queues a new probe and returns that probe’s report; nothing is cached. created_at on the result is the time of the probe you asked for, so a portfolio audit can verify freshness from the record itself.

Parameters

ParameterTypeRequiredDescription
domainstringYesDomain to probe. Its spelling is canonicalized but this tool removes no labels (the probe itself checks both the apex and www). Unicode names are accepted and sent as punycode, and the UTS-46 label separators 。, . and 。 are read as dots. Trailing root dots (example.com., example.com..) are accepted and removed. IP literals, single labels (localhost) and an underscore in the registrable domain (exa_mple.com) are rejected before any request is made. See datapulse_help(topic="normalization").

There are no other parameters.

What counts as a valid domain. Surrounding space and every trailing dot are trimmed, the name is lower-cased and converted to A-labels, and it must be 253 octets or fewer with each label 1 to 63 characters of letters, digits, hyphen or underscore, not beginning or ending with a hyphen.

Two restrictions apply to the top-level label alone, and both are what separate a domain name from something else:

  • It is never all digits, so 3.14 and 1.1.1.1 are rejected (RFC 3696). This is the rule that distinguishes a name from a dotted-quad address.
  • It never contains an underscore, so foo._com is rejected. Service labels elsewhere are unaffected: _dmarc.example.com and _443._tcp.example.com are valid inputs.

One restriction applies to the registrable domain: it cannot contain an underscore either, so exa_mple.com is rejected. DNS allows _ in an owner name, but no registry registers one, and this probe reports on a registered name.

A leading digit is fine, which is the natural wrong guess. 1password.com, 7-eleven.com and 333oracle.xyz are all accepted; RFC 1123 relaxed the older letter-first rule. Only the top-level label is restricted.

Timing

Three different limits apply, and they are not the same number:

LimitValueMeaning
Probe budget3 s per DNS lookup set, 2 s per TCP connect / TLS handshake / HTTP hop, 2 s per QUIC handshakeInside the report as timeout_sec, tcp_timeout_sec, quic_timeout_sec. A healthy domain finishes in 1.5–3 s. The probe’s phases add up to 16 s when every server in every phase hangs, and a whole-run deadline (max_time_sec, 18 s) caps it, so a report is always written; a run cut off there carries deadline_reached: true.
Worker kill20 sThe worker stops a probe that has not finished and stores status: "failed".
Tool wait30 sHow long this tool holds the request open. If the probe has not finished, the tool reports that the lookup is still running; the job completes server-side and a fresh call returns a new probe.

What is probed

  1. DNS records, DNSSEC-validated: A, AAAA, MX, TXT, NS at the apex; A, AAAA for www. Each lookup carries a status and a trust level. Apex or www addresses inside reserved ranges (RFC 1918, loopback, link-local, CGNAT, documentation, multicast, ULA) are an error, listed under reserved_addresses, and not probed (ports skipped).
  2. DNSSEC state of the zone, with DS and DNSKEY presence.
  3. Delegation: a trace from the root servers compares the NS set the parent zone delegates to with the NS set the zone itself serves. This walk deliberately bypasses the recursive resolver.
  4. Nameserver audit (nameservers, zone apexes only): every NS name is resolved (a CNAME or unresolvable name is an error) and every address is asked for the zone SOA non-recursively over UDP, TCP and with EDNS. Not authoritative or unreachable is an error; no TCP or no EDNS a warning; SOA serial drift a warning. Fewer than two nameservers is an error; all IPv4 in one /24 or all IPv6 in one /48 is a warning. Parent glue is compared with the zone’s own addresses (missing glue an error, a differing address a warning). No zone transfer is requested.
  5. Web reachability: TCP connect to ports 80 and 443 on every A and AAAA address of the apex and www. Port 25 is never probed.
  6. TLS on 443, every address that answered (tls): the chain is classified valid, expired, not_yet_valid, hostname_mismatch, self_signed, incomplete_chain, untrusted_root, invalid or handshake_failed; anything but valid is an error. valid means the chain as served verified, with no repair needed. incomplete_chain means the server omitted the intermediate and the chain verified only after the probe fetched it from the certificate’s AIA URL, which is named in that address’s tls.error. Browsers usually perform that fetch themselves, so an incomplete chain often looks fine in a browser while failing curl, Java and some mobile clients. chain names one defect and chain_problems lists them all. The certificate’s subject, issuer, validity, days_remaining, SANs, whether it covers apex and www, key type and fingerprint are reported. Two extra handshakes test TLS 1.0 and 1.1 acceptance (tls10, tls11: null when the handshake could not be attempted, which is not a refusal); accepting them, and negotiating below TLS 1.3, are info. Certificates that differ across a host’s addresses warn only when they differ in validity or in the names they cover.
  7. HTTP (http on 80, https on 443, per address): one GET / with the proper Host header; status, Location, Server and parsed HSTS (max_age, include_subdomains, preload). Every address 5xx on a port is an error; some 5xx or all 4xx a warning; port 80 serving content instead of redirecting a warning; HSTS max-age under 180 days a warning. HSTS absence is a fact, not a warning. hsts_preload answers whether browsers enforce HSTS for this name, from a cached copy of the Chromium preload list (the list is fetched once per worker, never per domain). That includes coverage by an ancestor entry with includeSubDomains, in which case hsts_preload_covered_by names the ancestor: any name under the app, bank, dev or page TLDs reads preloaded covered by the TLD. hsts_preload_policy is the Chromium policy of the covering entry and decides whether a header is owed. bulk-legacy, bulk-18-weeks and bulk-1-year entries were submitted through hstspreload.org and stay listed only while they keep serving a compliant header; those warn in two distinguishable ways, because the fixes differ: no HSTS header at all on this response, or one that does not meet the preload bar (max-age of at least a year, includeSubDomains, preload). google, custom, public-suffix and the other hand-kept policies carry no such obligation and never warn: gmail.com is policy google, answers https://gmail.com/ with a bare 301 and no header, and remains preloaded. A header carrying preload without meeting the bar warns too, for a name that is not on the list. Which response is read: the header comes from the queried name’s own GET / on 443 and nowhere else. Redirects are not followed for this, deliberately: HSTS is per-host, so a header served by the redirect target (mail.google.com for gmail.com) says nothing about the name that was asked about, and a missing header on a redirecting apex is a correct reading, not a probe fault. A request that failed before a response arrived (https.error, no status) yields no HSTS finding either way. Report what was observed (the policy, the status read, header present or absent) and do not guess at the operator’s reasons for it.
  8. Redirects are not followed (since 2026-10-06; the report header carries "redirect_log": false and there is no redirects key). Each address’s http and https entry is one response with its status and Location, which is enough to see that a name redirects and where the first hop goes. The full chain a visitor’s browser follows is the scrape’s redirect_chain: call datapulse_scrape_submit(url=..., wait=true) or read datapulse_domain_overview’s scrape, and read loops, https-to-http downgrades and chains ending in 4xx/5xx there. Two findings still come from the per-address responses: an address redirecting to the very URL it was asked for is an error (redirect_self), and addresses that answered the same URL differently within one run warn (http_response_inconsistent, listing each answer with its count). Reports from before 2026-10-06 carry a redirects object and the redirect_loop, redirect_downgrade, redirect_hop_limit, redirect_broken and redirect_ends_error findings; current reports never do.
  9. QUIC / HTTP3 on every address of both names, so every address entry carries a quic object and the “works on another address but not here” warning is reachable within a single address family, not only across families. A failed probe says why in reason (timeout for a host that drops UDP, tls_rejected with tls_alert and tls_alert_code for one that answers but refuses h3, which is how a CDN with HTTP/3 disabled presents, and the rarer resolve_failed, version_negotiation, stateless_reset, transport_error, application_error, listen_failed, invalid_args, other).
  10. Mail (mail, zone apexes only): DMARC at _dmarc (missing or p=none warn; multiple or unparsable records error); SPF evaluated with include/redirect chains followed and DNS-querying terms counted, every evaluation charged as RFC 7208 requires so a domain included from two places costs its lookups twice (over 10 is a permerror and an error, as are multiple records, +all — including one reached through redirect= or an included record — an include loop and unknown mechanisms; an include whose lookup did not complete warns as unchecked rather than counting as void; ?all, ptr, missing all, void lookups and includes without SPF warn; the apex TXT reply size without EDNS is measured as txt_answer_octets and warned past 450 and 512 octets, as is any include whose own TXT answer exceeds 512 octets, since a plain-UDP resolver may not receive it); every MX target must resolve and not be a CNAME or IP literal (errors); DKIM probed at the selectors google, selector1, selector2, default, k1, s1, mail, dkim (found selectors reported, a revoked empty key warns); MTA-STS record and policy checked against the MX set, the policy host resolved through the probe’s own validating lookups; TLS-RPT presence. A null MX is reported as “accepts no mail”. No SMTP connection is made.
  11. CAA (caa): records at the apex and www (www falls back to the apex records when it publishes none) are compared per host with the issuer of the certificate that host actually served, and a wildcard certificate against issuewild rather than issue. A CA the governing records forbid is an error for that host, so a domain can be sound at the apex and fail at www. No CAA at all means any CA may issue and is a fact.
  12. DANE / TLSA (tlsa): _443._tcp records for apex and www matched against every served chain. No match anywhere is an error; records in an unsigned zone a warning.
  13. Wildcard (wildcard): random 12-letter labels are looked up to see whether the zone answers names nobody published. Three that all answer make it present, one definitively denied makes it absent, and a probe that never came back makes it unknown rather than a false clean bill. When www resolves to exactly the wildcard’s addresses the report says www_via_wildcard with a warning; a wildcard on its own is data, not a fault.
  14. Resolver reachability over IPv4 and IPv6, measuring the resolver the probe is configured to use rather than the domain under test. The worker’s resolver is IPv4-only, so resolver_reachable.ipv6 always reads skipped: resolver has no ipv6 address in production. families lists the address families used for the web probes, not the resolver transport; IPv6 web probes run regardless.

Response

The response is the lookup record. raw_output is the probe report, verbatim.

FieldMeaning
idJob id of the probe this call queued
domainThe probed domain as the API reports it
domain_hashSHA-256 as the API computes it (the shared dpdomain convention: www-stripped lowercase punycode); joins with datapulse_domain_overview and with domain_hash in datapulse_live_dns
statuscompleted when the probe ran (healthy or not); failed when the probe tool itself could not run
raw_outputThe report (absent when status is failed)
errorWhy the probe could not run (only when status is failed)
created_at, completed_atWhen the probe was queued and when it finished
query_time_ms, total_time_msProbe duration and end-to-end duration on the worker
submitted_domainWhat you sent, when normalising it changed a non-ASCII name into domain. Absent otherwise. A fullwidth homograph such as example.com folds to example.com, so the report describes the legitimate domain, and this field is the only record that a different name was submitted. raw_output.unicode_domain does not cover it, because that appears only when an xn-- label survives

A multi-address domain produces a report of roughly 5–15 KB.

Report reference

Every key of the report, with its type and meaning, plus the conventions (which objects are omitted and when, which arrays are always present) and the enumerations, are in a companion topic:

datapulse_help(topic="domain_health_fields")

Reading the verdict

status is "completed" even when the domain is broken. The verdict is inside the report:

  • raw_output.ok — true when errors is empty.
  • A dead zone is one finding. When the parent delegates the zone but no delegated nameserver answers for it (every address refuses or stays silent), raw_output.errors holds exactly one entry, no delegated nameserver answers for the zone: <each nameserver and what it did> (code zone_unreachable), and nothing else is reported: no lookup timeouts, no SERVFAIL, no mail or web findings, since none of them could work. If even one nameserver answers, the full report is produced.
  • raw_output.errors — conditions that make ok false: apex NXDOMAIN; a name whose lookups all answered and returned no record of any type, reported as apex <name> has no records of any type (see below, since this is how a nonexistent name in many signed zones presents); apex has no NS; DNSSEC bogus or servfail; delegation mismatch, not_delegated, no_child_answer, child_no_ns or error; a lookup that failed or timed out; resolver unreachable over an enabled family; reserved addresses in DNS; any certificate chain problem; every address 5xx on a port; an address redirecting to itself; DMARC records that are multiple or unparsable; SPF permerror (over the lookup limit, multiple records), +all, unknown mechanisms; MX targets that are CNAMEs, IP literals or unresolvable; MTA-STS problems in enforce mode; nameservers that are CNAMEs, that the resolver says have no address, that answered but disclaimed authority, or that were silent on every one of their addresses; fewer than two nameservers; missing glue; a certificate issuer the CAA records forbid (per host); TLSA records matching no served certificate. A bogus or servfail DNSSEC verdict yields one DNSSEC error; the per-lookup failures it explains are folded into it. Nameserver problems are reported once per nameserver name (nameserver <name>: <reason> on N of M addresses). A delegation whose servers answered with an empty NS set says so, delegated NS servers answered with no NS records (NODATA): the zone has no apex NS RRset, rather than reporting silence, and that condition is counted once rather than as both a missing apex NS and a delegation error.
  • raw_output.warnings — advisory, do not affect ok: no A/AAAA at apex or www (these fold into the single no-records-of-any-type error when the name has nothing at all); www name does not exist; no MX or a null MX (RFC 7505); no SPF in TXT; name is not a zone apex (delegation and zone DNSSEC checks skipped); a name reserved by RFC and not served by the global DNS, where the delegation and DNSSEC checks do not apply; DNSSEC island or unknown; an address with no listener on 80 or 443; an address that was not probed (reserved address), which is a deliberate policy skip rather than a connectivity failure; an address where HTTP on 80 answers but HTTPS on 443 does not; QUIC/h3 working on another address of the host but not this one; certificates expiring within 30 days; a certificate not covering the sibling name; certificates across a host’s addresses that differ in validity or coverage; some addresses 5xx or all 4xx; the same URL answered differently across addresses within one run; clear-text HTTP without redirect; a preloaded domain with a bulk-* hsts_preload_policy that served a response on 443 carrying no HSTS header (the warning names the status that was read); such a domain whose served header does not meet the preload requirements; an HSTS header carrying preload without meeting them; the preload list could not be consulted; missing DMARC; a malformed DMARC pct or sp; SPF ?all, ptr, missing all, void lookups, includes without SPF or whose lookup did not complete; an apex TXT answer over 450 or 512 octets, or an SPF include whose own TXT answer exceeds 512 octets, so a plain-UDP resolver may not get it (RFC 7208 §3.4; include:amazonses.com is 523 octets, so every domain including it carries this warning); revoked DKIM keys; a zone that answers every _domainkey selector, so no selector could be verified; MTA-STS problems in testing mode; nameservers without TCP or EDNS; a nameserver silent on some of its addresses while the rest answer authoritatively; a nameserver or MX target whose address lookup did not complete; SOA serial drift; low prefix diversity; glue mismatch; TLSA in an unsigned zone; www answered by a wildcard. A domain whose HTTPS is entirely unreachable is still ok: true with one warning per address — filter on the web section or the warnings, not only on ok.
  • raw_output.findings (reports from 2026-10-05 on) — every result as {code, severity, host, message}. code is stable; key on it rather than on the message. severity is fail, warn or info: fail entries are exactly errors and warn entries are exactly warnings, in order. warn is a defect worth fixing. info is a configuration fact that many well-run domains share and that says nothing on its own: no AAAA, no MX or a null MX, no www, a wildcard www, TLS 1.0/1.1 kept for legacy clients, no TLS 1.3, HSTS max-age under 180 days, DMARC p=none, a certificate 7–29 days from expiry, an SPF TXT answer over 512 octets, a firewall answering the probe with 401/403/429 (http_probe_refused), SOA serial skew, nameservers in one IPv6 /48 (anycast). Reports from 2026-10-05 builds also list info entries in warnings; later builds list them in findings only. Either way, read severity from findings, never from which array a sentence sits in. A flagship such as wikipedia.org carries only info. The code table is in datapulse_help(topic="domain_health_fields").

status is "failed" (with an error field and no raw_output) only when the probe tool itself could not run — a usage error, a missing helper binary, or the 20-second worker kill. It says nothing about the domain.

Names that do not exist

Do not treat NXDOMAIN as the test for whether a name exists. A signed zone using compact denial of existence answers NOERROR with no records rather than admitting a name is absent, so a missing name under such a zone never returns NXDOMAIN. Cloudflare’s zones do this. Judging by the response code alone gives two names that equally do not exist opposite verdicts, depending only on how their provider phrases the denial.

The report judges the meaning instead: when every apex lookup answered and none returned a record, it fails with apex <name> has no records of any type, matching the NXDOMAIN case. The discriminator does not parse NSEC bitmaps; it relies on a name that someone created having at least one record of some type, since a mail-only host still has an MX and a verification host still has a TXT. Requiring every lookup to have answered keeps a failed probe from being read as an empty name, which is the same rule the rest of the report follows.

For a caller this means a typo now returns ok: false whichever provider hosts the zone, and it arrives as one error rather than a scatter of per-type warnings.

Names outside the global DNS

A name under invalid, test, localhost, example (RFC 6761), local (RFC 6762), onion (RFC 7686) or home.arpa (RFC 8375) is reserved and never resolves by definition.

Such a name needs special handling because a validating resolver answers it locally, and the denial it synthesises is unsigned. Read naively that looks like a broken trust chain, which would turn the resolver’s own behaviour into a security verdict about the name. So the report carries reserved_name with the RFC, dnssec.state reads unknown rather than bogus, the delegation, nameserver and mail checks are skipped, and one warning explains why.

A name that simply does not exist also drops the mail section, for a plainer reason: there is no zone to configure, so a missing DMARC record is not a finding.

example.com and its siblings are reserved for documentation but are really delegated, so they are checked like any other domain.

Names inside a zone

A name that is a host rather than a zone apex is reported with not_a_zone: true, enclosing_zone set when a SOA revealed it, delegation.status: "not_a_zone", and a warning that the delegation and zone DNSSEC checks were skipped. Two different shapes land here:

  • Its NS query returned no records, as for mail.google.com or a TXT-only name such as _dmarc.example.com.
  • It is a CNAME, as gist.github.com is to github.com. RFC 1034 forbids a CNAME coexisting with other data, and an apex must carry NS and SOA, so a CNAMEd name is definitionally not an apex.

In the CNAME case dns.apex.NS has records, and they are not this name’s. The NS query follows the CNAME, so what comes back belongs to the target’s zone. Do not read those nameservers as serving the name you asked about, and do not conclude from their presence that the name is an apex: not_a_zone is the field that answers that, in both shapes. Four signals move together and any of them settles it — not_a_zone: true, delegation.status: "not_a_zone", and mail, nameservers and web.www all absent.

enclosing_zone may be absent for a CNAMEd name. Where present it names the zone the SOA came from, which for a CNAME is the target’s zone rather than the queried name’s parent: gist.github.com reports github.com, while old.reddit.com and deb.debian.org, whose targets are hosts inside someone else’s zone, report nothing because no SOA surfaces. mail and nameservers are omitted, because mail policy and the NS set belong to the zone. dnssec.state is taken from the validation of the answers themselves (detail says so). Such a name is ok: true when its own records and certificate are sound. Probe the enclosing zone for the zone-level checks.

Do not infer the shape of a name from how many labels it has. A delegated subdomain is commoner than it looks: www.cloudflare.com, data.gov.uk and api.openai.com are all genuine zone apexes with their own NS records, so they report not_a_zone: false and get the full zone treatment. In one sample of 25 subdomains, four were zones rather than hosts. not_a_zone follows the delegation, which is the point of the field, and it is the only thing that answers the question.

Note that this is a different question from whether a name is a registrable domain, which decides web.www and is judged by the Public Suffix List. www.cloudflare.com is a zone apex but not a registrable domain, so it reports not_a_zone: false and still has no web.www — nobody would configure www.www.cloudflare.com. The two fields answer different questions and can disagree without either being wrong.

Joining with other tools

domain_hash is the SHA-256 of the www-stripped lowercase domain — the same hash datapulse_domain_overview returns — so a health report and an overview for the same domain join on it.

Retention and retries

Results are kept for 24 hours and then removed. If the call reports that the lookup is still running, the job finishes server-side; call again for a fresh probe.

When to use

  • A domain is registered but “not working”: distinguish DNS breakage (NXDOMAIN, lame delegation, DNSSEC bogus), certificate breakage (tls.chain), and web breakage (nothing on 80/443, 5xx) in one call; for redirect loops or a chain ending in an error, read redirect_chain from datapulse_scrape_submit. See also datapulse_help(topic="why_missing").
  • Confirm a nameserver migration: delegation.status and the nameservers audit show whether parent and child agree and every server answers authoritatively with the same serial.
  • Certificate hygiene across a portfolio: tls.chain, cert.days_remaining, cert_consistent, TLS 1.0/1.1 acceptance, caa.hosts.
  • Mail posture without sending mail: mail.dmarc, mail.spf (evaluated, with lookup count), mail.mx, mail.dkim, mail.mta_sts, mail.tls_rpt. See also datapulse_help(topic="email_security").
  • Portfolio audits: run the probe per domain, filter on raw_output.ok, then key on raw_output.findings[].code and treat only warn and fail as needing action (on a report without findings, key on error and warning prefixes), and check created_at to confirm each report is from your run.

For plain record lookups use datapulse_live_dns; for registration data use datapulse_live_rdap.

Generated from the live server (DataPulse MCP 1.0.0) on October 7, 2026. Your AI assistant reads this page by calling datapulse_help(topic="domain_health").