DNS Health (dns-health)
Summary
DNS record resolution (A/AAAA/MX/CNAME/TXT) and lookup performance.
Classification
- Category:
SECURITY - Plugin id:
dns-health - Version:
1.0.0 - Target types:
WEBSITE,API,WEBSHOP - Weight class:
LIGHT - Risk level: not set on plugin object
- Browser required: No (HTTP / Node / other — see source)
- Tier / group: Tier 1 — HTTP-only
Schedule
- scheduleHints:
{ defaultInterval: '0 */6 * * *', priority: 6 } - Prerequisites: None declared on this plugin.
Configurable inputs
Public keys are derived from inputSchema: z.object({ ... }) (underscore-prefixed keys are runtime-only and omitted here).
| Field | Notes |
|---|---|
expectedRecords |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
slowThresholdMs |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
Runtime / injected config
- None documented beyond standard worker context (
target,config,logger,reportProgress). Underscore-prefixed keys are internal.
Checks that produce findings
These checks run inside this plugin during a single test run. They are not separate tests in the database — each becomes a Finding linked to the Run for dns-health.
| Check | Typical severity | Why |
|---|---|---|
| Slow DNS resolution (per record type vs threshold) | WARNING | Resolver latency above threshold adds TTFB on every new connection and may indicate overloaded or distant authoritative DNS. |
| No A record (resolution failed) | WARNING | Without IPv4 A records, many clients cannot resolve the hostname — the site may appear down even when AAAA or CNAME exist elsewhere. |
Expected record missing (when expectedRecords configured) |
WARNING | Team-configured expectations (e.g. SPF substring, specific MX host) catch drift after DNS migrations or partial cutovers. |
How each check works
- Hostname — Parses hostname from target URL; invalid URL →
failedwith no findings. - Record lookups — Sequentially resolves A, AAAA, MX, CNAME, and TXT via Node
dns.promises.Resolver. AAAA/MX/CNAME/TXT failures return empty arrays (no finding except A). - Slow resolution — Times each lookup; if elapsed ms >
slowThresholdMs(default 500), emits one WARNING per slow record type with timing evidence. - Missing A — If
resolve4()throws, emits WARNINGNo A record for {hostname}with the resolver error message. - Expected records — When
expectedRecordsis set, each expected string must appear as a substring in at least one returned value for that type; otherwise one WARNING per missing expectation. - Run outcome — Score 100 clean, 60 with warnings, 20 if any CRITICAL (none emitted today). Metrics store per-type resolve times (
-1on failure).
Caveats and concerns
- A-only hard failure — Missing AAAA, MX, CNAME, or TXT does not produce findings; IPv6-only or email-only misconfigurations may look healthy.
- Substring matching —
expectedRecordsusesincludes(), not exact DNS equality — partial matches can false-pass or false-fail depending on formatting. - Resolver dependency — Uses the worker host’s system resolver, not public DNS (1.1.1.1/8.8.8.8); split-horizon or geo DNS may differ from end users.
- No propagation check — Single snapshot; does not compare against prior runs or query authoritative NS directly.
Source
packages/test-plugins/src/plugins/dns-health.ts