The terminal NXDOMAIN catch-all added in #874 also answers NXDOMAIN for the zone apex, actors.resources.substrate.ate.dev, and for <atespace>.actors.resources.substrate.ate.dev. Neither is an absent name: the apex exists by definition, and the zone answers for any well-formed <actor>.<atespace> pair, so every <atespace> label has children. Both are empty non-terminals, and the correct answer for one is NOERROR with an empty answer section, not NXDOMAIN.
NXDOMAIN asserts something stronger -- RFC 8020, "NXDOMAIN really means there's nothing below" -- so a resolver that caches it for <atespace> may decline to resolve any actor in that atespace. That is a hard resolution outage rather than a degradation, which is why it is worth tracking even though nothing hits it today.
Latent for now: it needs a resolver in front that both queries the intermediate name (QNAME minimisation, RFC 7816) and applies NXDOMAIN cuts. kube-dns stubDomains and the CoreDNS forward plugin pass the full qname through, the CoreDNS cache plugin caches per (qname, qtype) without aggressive negative caching, and musl and glibc do not cache at all.
The fix is one more template block before the catch-all, scoped by a match carrying the apex and single-label patterns, with rcode NOERROR, the same SOA authority record, and fallthrough. Ordering is load-bearing: after the actor NODATA block, before the catch-all. Worth deciding first whether an apex SOA or NS query should be answered properly instead, in which case file/auto with a real zone is a better shape than a fourth template block.
Reproduced against coredns/coredns:1.11.1, the pinned image: A ns1.actors.resources.substrate.ate.dev and SOA actors.resources.substrate.ate.dev both return NXDOMAIN. corefile.go carries a TODO pointing here. Follow-up to #874.
The terminal NXDOMAIN catch-all added in #874 also answers NXDOMAIN for the zone apex,
actors.resources.substrate.ate.dev, and for<atespace>.actors.resources.substrate.ate.dev. Neither is an absent name: the apex exists by definition, and the zone answers for any well-formed<actor>.<atespace>pair, so every<atespace>label has children. Both are empty non-terminals, and the correct answer for one is NOERROR with an empty answer section, not NXDOMAIN.NXDOMAIN asserts something stronger -- RFC 8020, "NXDOMAIN really means there's nothing below" -- so a resolver that caches it for
<atespace>may decline to resolve any actor in that atespace. That is a hard resolution outage rather than a degradation, which is why it is worth tracking even though nothing hits it today.Latent for now: it needs a resolver in front that both queries the intermediate name (QNAME minimisation, RFC 7816) and applies NXDOMAIN cuts. kube-dns
stubDomainsand the CoreDNSforwardplugin pass the full qname through, the CoreDNScacheplugin caches per (qname, qtype) without aggressive negative caching, and musl and glibc do not cache at all.The fix is one more
templateblock before the catch-all, scoped by amatchcarrying the apex and single-label patterns, withrcode NOERROR, the same SOA authority record, andfallthrough. Ordering is load-bearing: after the actor NODATA block, before the catch-all. Worth deciding first whether an apexSOAorNSquery should be answered properly instead, in which casefile/autowith a real zone is a better shape than a fourthtemplateblock.Reproduced against
coredns/coredns:1.11.1, the pinned image:A ns1.actors.resources.substrate.ate.devandSOA actors.resources.substrate.ate.devboth return NXDOMAIN.corefile.gocarries a TODO pointing here. Follow-up to #874.