A domain name in the RDATA section written without a trailing dot is relative to the zone origin (RFC 1035 §5.1), so "www CNAME host" in example.com. means host.example.com. The qualifier ran on the record after dns.NewRR had already resolved every RDATA name against the root, which turns "host" into "host." and makes the two indistinguishable -- relative() saw the trailing dot and left it alone. Every relative CNAME, NS, MX, PTR, SRV, NAPTR, SOA and SVCB target therefore pointed at the DNS root, which showed up as a local zone answering a CNAME with "host." and the alias target holding no local answer. Qualification now happens in assemble on the token stream, before the record is built, using a table of the RDATA positions that hold a name per type; names that already end in a dot stay absolute, so the RPZ targets "." and "rpz-drop." and the null MX targets are unaffected. Fix three wrong expectations in the localzone tests while here. The loop fixture was built with dns.NewRR on "alias.example.com", which cannot parse because the RR library wants a TTL and class column, so the expected record now spells them out. The origin-derivation fixture used "a" as an owner name, and a leading token that names an RR type reads as an omitted owner, which has no previous owner to inherit on the first line of a file; the owner is now a word. The merge test counted the SOA, but it is zone metadata rather than a queryable record, so two files contribute three records. The holder race test also looked up a name from the base zone while the holder was serving a store compiled from other.test., which no answer could satisfy; it now accepts either store's data.