ROS suffers a DNS cache poisoning issue.

Hi Fairly sure this is true, welcome anybody to repeat the setup and if I am correct.
On commissioning in the most excellent and highly recommended Technitium DNS/DHCP Server ( https://technitium.com/dns/ https://github.com/TechnitiumSoftware/DnsServer ) I started to get a problem where some services seemed to vanish. At first I assumed I’d made a mistake with the DNS configuration or the hosts were missing (or failing to use) a DNS suffix.
Then I realised this:

Setup:
If the DNS in ROS is configured to be caching only, i.e. has no static addresses.
And there is another proper DNS in the system, e.g. ROS may be a gateway and hence must have DNS turned on as the external DNS address can change, the real DNS does not know that.
And (possibly) IPV6 is enabled, but not used. I.e. link local IPV6 only. Though IPV6 AAAA requests are completely valid on an IPv4 only network.
Then this happens:

Sequence:
An app on client1 does a query www.domain.local AAAA (i.e. IPV6 address for an internal host. Likely because it’s host has an IPV6 address)
The query arrives at ROS
ROS forwards this to DNS as it does not know the answer, as there is no answer.
DNS answers correctly www.domain.local AAAA NXDOMAIN as our internal services are IPV4 only, this service is not on IPV6.
DNS sends this reply to ROS
ROS forwards the reply onto the client, caching it as it does. There is no setting for NXDOMAIN timeout, so it’s set to 1 day.
This would prompt the client’s app to retry with another new query for www.domain.local A (ipv4) and expect to get a valid answer.
But though the first query is forwarded from ROS, it is not true that ROS always sees this 2nd query, and even if it did it would not matter…
because:
ROS caches the first response as www.domain.local NXDOMAIN 0.0.0.0 (note the lack of AAAA) for 24 hours.
Client does another request either directly to ROS, or because it’s in an list of possible resolvers, no matter, it will answer incorrectly as it thinks it knows the answer and does not forward.
e.g. Client2 (or client1) queries www.domain.local A
ROS answers from it’s cached record of www.domain.local NXDOMAIN. !!!
Client goes “WTF”?

Technitium has some great tools for DNS manipulation so, I am now trying to prevent it replying to ROS when the forwarded query is AAAA…
It has plugin apps for that sort of thing.
Another work-round or bug-fix suggested?

I.e. ROS should cache the query type, in this case AAAA (including TXT, SRV, etc) not just the address even for NXDOMAIN replies otherwise it poisons it’s own DNS.

let the pro replay.

This is totally wrong, please read up on what NXDOMAIN really means. And then you’ll understand why NXDOMAIN is not cached with the record type:

https://bluecatnetworks.com/blog/what-you-can-learn-from-an-nxdomain-response/

NXDOMAIN means “non-existent domain”, which is returned when the domain does not exist at all, NOT when the domain exists but doesn’t have the record type being queried. In case of an AAAA query, if there exists any other record for the domain (SOA, A, MX, etc…) NOERROR should be returned, not NXDOMAIN, and the result for AAAA is just empty:

NOERROR.png
Here are some tests for you. First is a type=A query for a domain that only has IPv4:

record-present.png
As expected, we get NOERROR and answers=1, and the IP address. Now let’s query for the AAAA record, which does not exist:

no-record.png
As you can see, the code is still NOERROR, and not NXDOMAIN like you thought. The answers is empty (answers=0) because the AAAA record does not exist.

You only get NXDOMAIN when you query for a domain/subdomain that does not exist (has no record at all):

non-existent.png
I hope that now you can see that it doesn’t make sense to save the record type with the cached NXDOMAIN result! You should either replace your DNS software or configure it so that it correctly returns NOERROR for an AAAA-query when an A record (or any other record type) is present but no AAAA.

I was also trying to reproduce this where for ROS DNS upstream Pi-Hole is set, static record is added on Pi-Hole only for IPv4 address and there is no such issue.
1st AAAA query for existing domain on Pi-Hole to ROS DNS - NOERROR is responded from Pi-Hole and it is not cached in ROS DNS since there is no IPv6 address record for such domain, same response is propagated from ROS DNS
2nd A query for same domain to ROS DNS - NOERROR is responded from Pi-Hole with IPv4 address record, such record is cached in ROS DNS.
For non existing domain query - NXDOMAIN is responded from Pi-Hole and it is cached in ROS DNS which is logical because there is no need to query upstream for non existing domain just because type is changed in query…
So issue is in upstream DNS as @CGGXANNX explained where NOERROR needs to be responded if domain exists even there is no IPv6 record, it seems that Technitium DNS is not that great after all or is bad setup…