checker: report transient mid-chain and final rcodes as Unknown, not Crit/Warn
All checks were successful
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing

SERVFAIL/REFUSED from every auth server means the record could not be
observed, not that the zone published a negative answer. Mark such rcodes
transient on TermRcode terminations and final A/AAAA lookups so chainRcodeRule
reports Unknown instead of flapping the check into Crit/Warn; definitive
NXDOMAIN answers still drive Crit (mid-chain) and Warn (final).
This commit is contained in:
nemunaire 2026-06-18 11:22:00 +09:00
commit 65687ce375
4 changed files with 65 additions and 16 deletions

View file

@ -47,9 +47,10 @@ type ChainTermination struct {
Subject string `json:"subject,omitempty"`
Detail string `json:"detail,omitempty"`
Rcode string `json:"rcode,omitempty"` // only with TermRcode
// Transient is meaningful with TermQueryErr: true when the query could not be
// completed because of a transport/resolver fault (could not observe), false
// when it stems from definitive evidence such as a target with no locatable apex.
// Transient is meaningful with TermQueryErr and TermRcode: true when the failure
// could not be observed as a definitive answer (a transport/resolver fault, or a
// SERVFAIL/REFUSED from every auth server), false when it stems from definitive
// evidence such as a target with no locatable apex or an authoritative NXDOMAIN.
Transient bool `json:"transient,omitempty"`
}
@ -73,7 +74,11 @@ type AliasData struct {
FinalTarget string `json:"final_target,omitempty"`
FinalA []string `json:"final_a,omitempty"`
FinalAAAA []string `json:"final_aaaa,omitempty"`
FinalRcode string `json:"final_rcode,omitempty"`
// FinalRcode is the non-NOERROR rcode of the final A/AAAA lookup, if any;
// FinalRcodeTransient is true when it was a SERVFAIL/REFUSED (could not observe)
// rather than a definitive negative answer.
FinalRcode string `json:"final_rcode,omitempty"`
FinalRcodeTransient bool `json:"final_rcode_transient,omitempty"`
// Coexisting is populated only when Owner has a CNAME.
Coexisting []CoexistingRRset `json:"coexisting,omitempty"`