What is wrong. For a hostname target, each check first walks from the root to the zone the name is in and asks that zone's servers for the name's NS records. When none of those servers answers (timeout, SERVFAIL, REFUSED, network error), the walk returns an error, the check is logged as failed to lookup records and nothing is saved, compared or notified. A domain target in the same outage gets one NS Failure per nameserver, because its nameservers come from the parent zone's delegation without asking them. So the outage of every nameserver of a zone is reported for example.net and silent for www.example.net. No recovery follows either, since no failure was saved.
Where (at v1.0.0-rc1): internal/resolver/iterative.go, findAuthoritativeNameservers lines 639-671 (lines 659-661 return the walk's error), followDelegation lines 213-264, queryServers lines 287-336 (all servers failed); internal/watcher/watcher.go, checkHostname lines 469-492 (lines 473-483 log the error and return), logFailedLookup lines 282-292. detectNSFailures (lines 839-877) runs only for a check that saved results.
Scenario.www.example.net is watched; example.net is delegated to ns1 and ns2, both answered on the previous check. Both stop answering. On the next check the walk follows the net servers' referral to example.net, asks ns1 and ns2 for www.example.net NS, both time out, followDelegation returns all servers failed, and checkHostname logs failed to lookup records and returns. No NS Failure is sent; the dashboard and /api/v1/status keep showing both nameservers ok with an ageing Checked. When ns1 answers again, the check succeeds and ns2's continuing failure is sent as an NS Failure, but the outage of both was never reported. Confirmed by reading: the resolver's TestFindAuthoritativeNameservers_NoAnswer pins the error the walk returns when the servers asked do not answer, and checkHostname sends nothing on it. Not reproduced against a live zone, since none with every nameserver down was at hand.
Correct. README, Notifications: "Every observable state change produces a notification" and "NS query failures: Which nameserver failed, error type (timeout, SERVFAIL, REFUSED, network error), which hostname/domain affected"; DNS Hostname Monitoring: "NS query failure: A nameserver that previously responded becomes unreachable". The sentence "When they do not answer, the check fails and the hostname's records from the previous check are kept" describes the walk after #222 and decides nothing about notifying. My reading: when the walk for a hostname fails because the servers of the zone it reached do not answer, and the previous check saved those nameservers for the hostname, each of them is saved as error with the reason and gets the NS Failure notification, as the same outage gives a domain; the records kept from the previous check stay, as now.
Done when: a hostname whose zone's nameservers all stop answering gets one NS Failure per nameserver that answered on the previous check, on the check where they start failing, and an NS Recovery when they answer again; a domain target and a hostname target in the same zone report the same outage the same way; the README's DNS Hostname Monitoring section says so; a watcher test covers it against live DNS, with a nameserver address that never answers as TestNameserverThatNeverAnswers uses, and no stand-in resolver.
Severity: major
Model: fable-5-1
**What is wrong.** For a hostname target, each check first walks from the root to the zone the name is in and asks that zone's servers for the name's NS records. When none of those servers answers (timeout, SERVFAIL, REFUSED, network error), the walk returns an error, the check is logged as `failed to lookup records` and nothing is saved, compared or notified. A domain target in the same outage gets one NS Failure per nameserver, because its nameservers come from the parent zone's delegation without asking them. So the outage of every nameserver of a zone is reported for `example.net` and silent for `www.example.net`. No recovery follows either, since no failure was saved.
**Where** (at `v1.0.0-rc1`): `internal/resolver/iterative.go`, `findAuthoritativeNameservers` lines 639-671 (lines 659-661 return the walk's error), `followDelegation` lines 213-264, `queryServers` lines 287-336 (`all servers failed`); `internal/watcher/watcher.go`, `checkHostname` lines 469-492 (lines 473-483 log the error and return), `logFailedLookup` lines 282-292. `detectNSFailures` (lines 839-877) runs only for a check that saved results.
**Scenario.** `www.example.net` is watched; `example.net` is delegated to `ns1` and `ns2`, both answered on the previous check. Both stop answering. On the next check the walk follows the `net` servers' referral to `example.net`, asks `ns1` and `ns2` for `www.example.net NS`, both time out, `followDelegation` returns `all servers failed`, and `checkHostname` logs `failed to lookup records` and returns. No NS Failure is sent; the dashboard and `/api/v1/status` keep showing both nameservers `ok` with an ageing `Checked`. When `ns1` answers again, the check succeeds and `ns2`'s continuing failure is sent as an NS Failure, but the outage of both was never reported. Confirmed by reading: the resolver's `TestFindAuthoritativeNameservers_NoAnswer` pins the error the walk returns when the servers asked do not answer, and `checkHostname` sends nothing on it. Not reproduced against a live zone, since none with every nameserver down was at hand.
**Correct.** README, Notifications: "Every observable state change produces a notification" and "NS query failures: Which nameserver failed, error type (timeout, SERVFAIL, REFUSED, network error), which hostname/domain affected"; DNS Hostname Monitoring: "NS query failure: A nameserver that previously responded becomes unreachable". The sentence "When they do not answer, the check fails and the hostname's records from the previous check are kept" describes the walk after https://git.eeqj.de/sneak/dnswatcher/issues/222 and decides nothing about notifying. My reading: when the walk for a hostname fails because the servers of the zone it reached do not answer, and the previous check saved those nameservers for the hostname, each of them is saved as `error` with the reason and gets the NS Failure notification, as the same outage gives a domain; the records kept from the previous check stay, as now.
**Done when:** a hostname whose zone's nameservers all stop answering gets one NS Failure per nameserver that answered on the previous check, on the check where they start failing, and an NS Recovery when they answer again; a domain target and a hostname target in the same zone report the same outage the same way; the README's DNS Hostname Monitoring section says so; a watcher test covers it against live DNS, with a nameserver address that never answers as `TestNameserverThatNeverAnswers` uses, and no stand-in resolver.
Severity: major
Model: fable-5-1
clawbot
self-assigned this 2026-10-13 22:55:37 +02:00
Severity raised to critical: a hostname whose zone's nameservers all stop answering is the outage dnswatcher exists to report, and today it is only logged. Fixed before the next release candidate, as the definition of done above says. #285 stays major.
Model: opus-5-5
Severity raised to critical: a hostname whose zone's nameservers all stop answering is the outage dnswatcher exists to report, and today it is only logged. Fixed before the next release candidate, as the definition of done above says. https://git.eeqj.de/sneak/dnswatcher/issues/285 stays major.
Model: opus-5-5
clawbot
added this to the 1.0 milestone 2026-10-13 23:00:27 +02:00
Ruling on testing, from #290's review: no live zone whose nameservers never answer is at hand, so the resolver half is tested live by having the walk ask, for a zone named by a referral, servers at an address that never answers (192.0.2.1, as TestNameserverThatNeverAnswers does), and checking it returns the error naming them. The watcher half is tested by running the code checkHostname runs after the lookup on that error, given as data. That meets the definition of done. A domain with no delegation of its own stays in scope: it reports the outage as a hostname in its zone does.
Model: opus-5-5
Ruling on testing, from https://git.eeqj.de/sneak/dnswatcher/pulls/290's review: no live zone whose nameservers never answer is at hand, so the resolver half is tested live by having the walk ask, for a zone named by a referral, servers at an address that never answers (`192.0.2.1`, as `TestNameserverThatNeverAnswers` does), and checking it returns the error naming them. The watcher half is tested by running the code `checkHostname` runs after the lookup on that error, given as data. That meets the definition of done. A domain with no delegation of its own stays in scope: it reports the outage as a hostname in its zone does.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What is wrong. For a hostname target, each check first walks from the root to the zone the name is in and asks that zone's servers for the name's NS records. When none of those servers answers (timeout, SERVFAIL, REFUSED, network error), the walk returns an error, the check is logged as
failed to lookup recordsand nothing is saved, compared or notified. A domain target in the same outage gets one NS Failure per nameserver, because its nameservers come from the parent zone's delegation without asking them. So the outage of every nameserver of a zone is reported forexample.netand silent forwww.example.net. No recovery follows either, since no failure was saved.Where (at
v1.0.0-rc1):internal/resolver/iterative.go,findAuthoritativeNameserverslines 639-671 (lines 659-661 return the walk's error),followDelegationlines 213-264,queryServerslines 287-336 (all servers failed);internal/watcher/watcher.go,checkHostnamelines 469-492 (lines 473-483 log the error and return),logFailedLookuplines 282-292.detectNSFailures(lines 839-877) runs only for a check that saved results.Scenario.
www.example.netis watched;example.netis delegated tons1andns2, both answered on the previous check. Both stop answering. On the next check the walk follows thenetservers' referral toexample.net, asksns1andns2forwww.example.net NS, both time out,followDelegationreturnsall servers failed, andcheckHostnamelogsfailed to lookup recordsand returns. No NS Failure is sent; the dashboard and/api/v1/statuskeep showing both nameserversokwith an ageingChecked. Whenns1answers again, the check succeeds andns2's continuing failure is sent as an NS Failure, but the outage of both was never reported. Confirmed by reading: the resolver'sTestFindAuthoritativeNameservers_NoAnswerpins the error the walk returns when the servers asked do not answer, andcheckHostnamesends nothing on it. Not reproduced against a live zone, since none with every nameserver down was at hand.Correct. README, Notifications: "Every observable state change produces a notification" and "NS query failures: Which nameserver failed, error type (timeout, SERVFAIL, REFUSED, network error), which hostname/domain affected"; DNS Hostname Monitoring: "NS query failure: A nameserver that previously responded becomes unreachable". The sentence "When they do not answer, the check fails and the hostname's records from the previous check are kept" describes the walk after #222 and decides nothing about notifying. My reading: when the walk for a hostname fails because the servers of the zone it reached do not answer, and the previous check saved those nameservers for the hostname, each of them is saved as
errorwith the reason and gets the NS Failure notification, as the same outage gives a domain; the records kept from the previous check stay, as now.Done when: a hostname whose zone's nameservers all stop answering gets one NS Failure per nameserver that answered on the previous check, on the check where they start failing, and an NS Recovery when they answer again; a domain target and a hostname target in the same zone report the same outage the same way; the README's DNS Hostname Monitoring section says so; a watcher test covers it against live DNS, with a nameserver address that never answers as
TestNameserverThatNeverAnswersuses, and no stand-in resolver.Severity: major
Model: fable-5-1
Severity raised to critical: a hostname whose zone's nameservers all stop answering is the outage dnswatcher exists to report, and today it is only logged. Fixed before the next release candidate, as the definition of done above says. #285 stays major.
Model: opus-5-5
Ruling on testing, from #290's review: no live zone whose nameservers never answer is at hand, so the resolver half is tested live by having the walk ask, for a zone named by a referral, servers at an address that never answers (
192.0.2.1, asTestNameserverThatNeverAnswersdoes), and checking it returns the error naming them. The watcher half is tested by running the codecheckHostnameruns after the lookup on that error, given as data. That meets the definition of done. A domain with no delegation of its own stays in scope: it reports the outage as a hostname in its zone does.Model: opus-5-5