09/04/2026 | Press release | Distributed by Public on 09/03/2026 19:48
One effective form of attack on the Domain Name System (DNS) infrastructure, including the root servers, is the so-called 'random name attack'. If you want to target the online availability of a particular domain name, then a random name attack will attempt to saturate the domain name's authoritative nameserver (or servers) with queries to resolve names in that zone. That can put the server (or servers) under such a level of load that 'legitimate' queries are no longer answered. The result is that the name goes dark and the denial-of-service attack is successful.
This attack is far easier to mount than many other forms of attack. It doesn't require crafting any advanced query packets, nor does it require a sophisticated level of control of the attack bots. All that's needed from each co-opted host is the ability to generate random names within the targeted domain and then pose DNS queries that use this random name. This is typically achieved within a simple script that needs no privileged access on the host.
The attack is effective in targeting the authoritative servers because of the way in which DNS handles 'no such domain name' () responses. The aim of the attacker is to bypass any local DNS resolver caches and place the authoritative server under pressure. If the distributed attack uses a name that exists within the target name space, the resolution response will be cached in the attackers' local recursive resolvers, and these recursive resolvers will essentially protect the authoritative name servers.
Even if the attack uses a nonexistent but constant query name, then resolver caching will still be effective. The recursive resolver will cache the fact that a DNS name does not exist and use this cached information to respond to subsequent queries for the same name.
If the attack uses randomly generated names, then the local caches are ineffective, as they only cache the specific query name, and each query for a new random name is passed to an authoritative server to resolve. Random query names effectively bypass the conventional DNS cache.
Understanding how the DNS handles requests to resolve nonexistent names is an important part of understanding how we can make the DNS more resilient to this form of random name attack. At APNIC Labs, we've been experimenting with seeding the DNS with queries to nonexistent domain names that are part of domains that we operate to focus on this aspect of the DNS.
The measurement methodology is very simple. We use a script embedded in an online advertisement (ad) to perform a measurement experiment and collect the query data on our server infrastructure. The script generates a DNS resolution query for a random nonexistent name where the only authoritative server(s) for these DNS names are part of the experimental setup. We can then observe DNS recursive resolvers querying our authoritative name servers for these DNS names, and use their query log for subsequent analysis. (Figure 1).
The ad is impressed on millions of endpoints per day, so we can quickly gain a view that encompasses much of the Internet's geographic and platform diversity.
Predicted results
We had an expectation about what we would see from this simple experiment. To explain this, we need some background on how DNS resolvers are configured.
Clients are loaded with the addresses of one or more DNS recursive resolvers. For example, my ISP provides two such resolver addresses, which are then passed to my devices by DHCP-based autoconfiguration.
When an application generates a DNS query, the localhost's name resolver library routines (the 'stub' resolver in the localhost) will send the query to one of these recursive resolver addresses. Because DNS is a User Datagram Protocol (UDP) protocol, there is no assurance that the end host's stub resolver will receive a response, so the stub resolver starts a timer when it launches the query. If the timer expires and no response has been received, then the query will be repeated. If there are multiple recursive resolvers configured in the host, then the repeat query may be directed to a different resolver. Successive timeouts may cause the stub resolver to issue further repeat queries to the set of configured resolvers.
The interval between successive queries may lengthen until a total query period has elapsed, at which point the query is abandoned if no response has been received. The timeout period between queries, the number of queries, and the total time that a query will remain active in a resolver varies according to the DNS resolver implementation and local configuration settings.
An example of one such approach is Microsoft's client resolver library. This stub resolver implementation uses a one-second timer and repeats the query if no response has been received. It will wait a further second and repeat the query, with a timeout of two seconds. This query will be repeated again with a four-second timer, and if there is still no response, the query will be terminated. The total time is a maximum of ten seconds and five queries.
If the stub resolver has been configured with two or more recursive resolvers, then the stub resolver will switch to use the second resolver if the first query does not elicit a response and then generate queries to all configured recursive resolvers with a four-second timer.
See the query repeat procedure documentation for more information.
It's not just the client stub resolver libraries that perform re-queries. A similar timeout mechanism is used in recursive resolvers, and these resolvers may also emit further queries when they do not receive a response. Where two or more authoritative nameservers are configured for a name, the repeat queries may be directed across the nameserver set.
Typically, we see a far more conservative approach to re-query from recursive resolvers than from end hosts. If both end hosts and forwarding resolvers use a very aggressive set of re-query timers, then a single query could potentially trigger a query storm on a loaded server, with the potential of turning a transient load event into an unintentional Denial-of-Service (DoS) attack!
The general rule of behaviour is that unresponsive servers will elicit further queries from resolvers, but these re-queries should not multiply to the extent that they impose a significant additional load on the server.
Let's also look at the response. When a name does not exist in a zone, there will be a DNS response sent back to the querier. This negative DNS response uses the DNS response code three, . The response indicates that the name is not contained in the zone, and the resolver should interpret this response as a terminating response to the query. This is a locally cacheable response, so repeated queries for the same name, no matter the query type, can be answered by the caching resolver from its local cache, for the Time to Live (TTL, or cache lifetime) of this negative response.
We can now answer the question: What were we expecting to see when we answer queries with ?
In an IPv4-only environment before the introduction of HTTP/3, then we would expect to see just a single query from each client, assuming that the authoritative server is answering every query and the combination of network delay and the server's processing delay is under the client's retransmit timer values. If the client-side stub resolver is a dual-stack client, then we may see two queries, as the and queries are usually generated in rapid succession. If the client uses an HTTPS query type to determine whether it can use HTTP/3, then we would also expect to see this query in the initial query set. So, we would expect to see up to three queries made in quick succession from a client stub resolver.
Where there is a long delay between the resolver and the server, or some level of packet drop, we may see repeat queries due to UDP timeouts.
2019 measurement
We conducted a negative response measurement in October 2019. A total of 60,210,983 measurements were used in this data set. The number of DNS queries seen at the authoritative servers for these non-existent domains was 142,631,272, or an average of 2.37 queries per queried unique name.
If every client had IPv6 capability and was querying for an IPv6 record and an HTTPS record, this query volume would be lower than the expectations we've just outlined. However, in 2019 the level of use of IPv6 was 24% of the sampled client population, and the HTTPS query was not being used. So the estimated query volume, if all responses were reliably passed back within the resolver's timeout interval, would be 75M queries, or just under half of the 142M queries that we observed at the time.
We operated four servers for the experiment, locating the servers in Singapore, Frankfurt, Dallas, and São Paulo. The end hosts were geo-located so that the name they queried would direct their DNS queries to the server that was closest to their location.
We observed Round-Trip Times (RTTs) to end hosts that were well within half a second for almost all measurement endpoints. If client software used a one-second re-query timer, then we expected well less than 10% of endpoints would experience a query timeout and perform a re-query. This average of 2.4 queries per unique name was well outside the anticipated result even when factoring in this UDP-triggered network delay re-query factor.
The result of this 2019 measurement exercise was a curiously high number of repeat queries, with no clear explanation of what caused this behaviour.
2026 measurement
Fast forward to 2026, and we wanted to see if anything had changed in the intervening seven years, so an extended version of this experiment was repeated in the first half of August 2026.
NXDOMAIN
In the period from 5 to 11 August 2026, we conducted the same experiment, using a pool of 115,750,503 endpoints, gathered using a Google Ad campaign across this period, collected from all parts of the Internet that are served Google Ads (the major exception in recent years is Russia).
The DNS names that the endpoints are attempting to resolve are all randomly constructed, so that prior cached responses cannot be used, and in all cases the authoritative servers return the response. The zone is not Domain Name System Security Extensions (DNSSEC) signed, so there is no additional factor of or records and their validation. In this experiment, our DNS authoritative servers support access over UDP and Transport Control Protocol (TCP), but no form of encrypted DNS transport such as DNS over TLS (DoT), or DNS over HTTP (DoH). The responses are short in size, so there is no truncation of responses, with the result that much of the observed DNS traffic is clear-channel DNS over UDP.
We observed 509,410,787 such queries in this period, counting those queries that arrived within 24 hours of the original placement of the measurement ad. That's an average of 4.40 queries per unique domain name, well above the average query rate of 2.4 queries that we observed in 2019.
There are a couple of factors behind this increased query volume. A Happy (web) Eyeballs dual-stack endpoint will launch two DNS queries back-to-back (roughly), for and records of the name. 48% of endpoints queried for both and records (up from 23% in 2019), while 51% of endpoints queried only for records (down from 74%), and 1% of endpoints queried for record only. An HTTPS-aware endpoint will also launch an HTTPS DNS query, and we observed 39% of endpoints generating queries for records.
With these 116M tests, this distribution of client capabilities would result in 218M queries if each of these query types (, , ) were queried just once. But we observed a total of 509M queries. The remainder of the observed query set (291M queries, or 57% of all queries) is due to some form of query repetition. On average, each repeated query was repeated a further 2.5 times.
As usual, averages conceal a wealth of detail. Of the 115,750,503 tested endpoints, we observed 67,316,541 endpoints, or 57%, completed the name resolution process using no more than one query for each of the query types they queried. That means that the remaining 48,433,962 endpoints generated 291,919,927 repeated queries, and the average query repetition rate was 6.03 for these endpoints.
This volume of what appears to be gratuitous queries in the DNS for a non-existent name is curious. Why is the DNS so averse to accepting a response from an authoritative nameserver? And why is this query repetition count close to double what we observed in 2019? Is this attributable to implementations of recursive resolvers, or is this an outcome of more complex DNS systems, like front-end query distributors and back-end DNS resolver engines?
There are all good questions, and I'll return to the topic of repeat queries in the DNS in a separate study. Here I'd just like to look at these issues of query repetition in the context of how to say 'no' in the DNS. Is the most efficient way to do so? How do the other forms of DNS negative responses fare when compared to behaviour?
NOERROR / NODATA
Oddly enough, it is not possible to ask if a name exists in the DNS. All queries have a query type, and the DNS query is asking for the resource set of the specified query type that is associated with the query name.
The query type is a potential exception to this generalization.
Early interpretations of the DNS specification tended to behave as if the query type was synonymous with a hypothetical ALL wildcard query type, and the response was expected to include all resource record sets that were associated with the query name. Some DNS server implementations still behave in this way by default.
However, there are a few problems with this behaviour. The response is invariably far larger than the original query, so the query can be used as a DNS reflection attack. This is made worse if the zone is DNSSEC-signed, as the response will include all the and resource records. It also assumes that the responding server has access to the full set of resource records for every label in the zone, which may not necessarily be the case, particularly in the case of dynamically served zones.
RFC 8482 Providing Minimal-Sized Responses to DNS Queries That Have QTYPE=ANY, provides the guidance that the server may use a single synthetic resource record to answer such queries, as is not required to be . This approach provides a compact response that remains consistent with DNS protocol specifics.
Some servers use the NS resource records as the response to an query, which again is consistent with the DNS specification.
An response 'over answers' the query, indicating that not only are there no resource records of the specified type associated with the query name, but the query name itself does not exist. A more constrained response is to indicate that the specified query type does not exist for this query name, but remain non-committal whether any other resource record type is defined for this name.
This form of response is the response, with a response code value of 0. It indicates that the query has been successfully processed without encountering any exceptional conditions, but the response contains no section as there are no resource records for the query type.
If a DNS resolver is asking for a collection of resource records, such as , and queries, and if it performs them in sequence, waiting for each response before proceeding to the next, then the response would reduce the query volume, as this response indicates that this name simply does not exist for all query types. The response would not prevent the other queries from proceeding in sequence. This is a minor consideration in this case, as most DNS resolvers perform these queries in parallel, so the query volume should be much the same whether the response is or .
To measure the performance of this form of negative response, we performed 115,571,398 tests and recorded 454,213,932 queries. That's an average of 3.93 queries per test.
Of these 115,571,398 tested endpoints, we observed 64,033,517 endpoints, or 55%, which completed the name resolution process using no more than one query for each of the query types they queried. That means that 51,537,881 endpoints generated repeating queries, and the average query repetition rate for these endpoints was 4.57 repeat queries.
If query count is the assessment metric for efficiency, then surprisingly is a slightly more efficient response than . If the domain is DNSSEC-signed, then the is smaller, as it contains two signatures as compared to the three signatures used in the response.
SERVFAIL
The response (code two) is also a form of a negative response. This response is used to indicate that the server was unable to generate a response to this query. This may be due to some internal error, or an error in the zone configuration. In the case of a DNSSEC-signed zone, this response may indicate a failure in a resolver's efforts to perform DNSSEC validation. More information may be provided in the form of an Extended DNS Error (EDE), but as the specification of EDE (RFC 8914) notes:
EDE content should be treated only as diagnostic information and MUST NOT alter DNS protocol processing.
RFC 8914The response is an equivocal response. It simply indicates that the responding server was unable to respond to this query.
It does not indicate:
The response does not have a TTL value, but the resolver receiving this response may cache this response for some locally defined period, and not repeat the query against this server for that period.
Most DNS resolvers, when presented with a response, will assume that there is a transient issue with the queried server. If the zone is configured with multiple servers, then a resolver would normally shift to querying other servers for the zone in its effort to get a response to the query. That implies that we would anticipate that any test of the efficiency of a response would observe a higher query count as compared to or . The multiplier function would be proportionate to the number of authoritative servers used to serve the zone.
In our experiment, we are using a single dual-stack name server. An IPv4-only or IPv6-only resolver would see this in a similar manner to a zone served by a single server, while a dual-stack resolver may see this as a zone with two servers. Approximately one half of our queries are handled by dual-stack resolvers, which would suggest that our test of the response should see a query volume that is 50% higher than that seen with the or tests.
We performed 138,643,924 tests against a server, and recorded 7,171,673,166 queries. This represents an average query volume of 51.29 queries per test, more than ten times that seen for and . Clearly, my assumption about resolver behaviour in response to a response is wildly incorrect!
3,702,576 tests were completed with just one query for each of the query types used by the resolver. A total of 6,920,490,780 queries were repeat queries, and that's an average of 51.59 repeat queries for each test that had repeat queries.
As a negative response, is extremely inefficient, and it imposes an additional query load on a server that is close to ten times the query load compared to the or responses. In the case of DNSSEC validation failure, there is little choice in the use of this code. A validating resolver wants to indicate that the queried name and type may exist, but it cannot provide a response due to the query including the DNSSEC flag and the resolver encountering validation failure.
Parenthetically, the response code is not 'protected' by DNSSEC, and if the DNS transaction is using DNS over UDP in the clear, an on-path attacker can alter the response code to to cause a large-scale increase in the query volume.
REFUSED
The response (code five) is used to indicate that the server received the query, but will not respond. There may be a few reasons, including access controls, recursion is requested but the server does not permit it, or the server is not authoritative for the domain.
The response is like the response in terms of being a negative response that provides no specific information about the existence of the query name or query type. However, is a policy response to the querier and is not indicative of a transient condition, while reflects a current situation that is presumed to be transient. This difference appears to influence the re-query behaviour of resolvers. A resolver is more likely to accept a response as a final response, while a response may cause further queries to probe whether the state is a transient condition that will be cleared in the near-term future.
We performed 115,415,259 tests for the response and recorded 1,324,355,211 queries. This represents an average query volume of 11.47 queries per test, which is significantly lower than what we observed for the response. We observed 47,625,165 tests that completed with just one query for each of the query types used by the resolver, and 1,106,379,779 queries were repeat queries, which is an average of 16.32 repeat queries per test.
The response appears to be midway between the explicit negative responses of and and the indeterminate response.
No response: Silence
The final negative response option tested was to simply not respond to queries for the tested query name and type at all.
In some ways this lack of information is not all that different to the and responses, but in this case the lack of response means that the resolver will need to rely on its UDP timeout settings to determine that the query was not successful, and the overall resolver timeout interval will determine when a resolver gives up on the resolution effort. Most resolvers are persistent in looking for a response unless there is an indication that the state that caused the negative response is likely to be persistent, so we should expect the query pattern to be closer to than .
We performed 11,6050,253 tests and observed a total of 9,685,775,212 queries. The average is 82.6 queries for each test. Some 2,519,191 tests completed with a single query. There were 9,466,474,491 queries that were repeat queries, and the average number of repeats was 83.38 queries per test. This is a more extreme version of the behaviour seen with the response.
Control: A/AAAA Response
To place the negative response data into context, we performed the same measurement on a query name using servers that always respond positively.
In this case, we performed 254,894,985 tests and recorded 875,316,423 queries, an average of 3.43 queries per test. 57% of tests elicited only a single query for each query type used in the test, and 408,891,797 queries were repeat queries, and the average number of such repeats was 3.80 queries per test.
This resolution profile is like the profile.
Conclusion
A summary of these results presented here is shown in Table 1.
The cases where there is a definitive negative response, namely and as well as the positive response, there is a common query repetition profile. On average, we see four queries per test. Between 55% and 60% of tests complete with a single query, and where repetition occurs, the average number of query repeats is between four and six.
Where there is no definitive response, the DNS slips into a behaviour mode that repeats queries. The response is accepted with a single response 40% of the time, but in other cases of the response, there is an average of a further 11 repeat queries. and responses show a more extreme pattern of repeat queries.
I find it somewhat surprising that in this experiment the test generates the smallest number of repeated queries for a negative response, while the more direct negation response, is slightly less efficient in terms of query count.
There are many questions raised by this data. Can we find causes of this query repetition? Is this related to UDP behaviour? If we shifted to a TCP transport, would this materially change the repetition profile? We'll explore these aspects of DNS behaviour in follow-up articles.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.