A unique lookup leaves your device, your real resolver fetches it from our server, and we record which resolver asked.
Most people assume the answer is whatever they set in their settings. In practice the path can be redirected by your operating system, your router, your ISP, a VPN, or a public Wi-Fi network, often with no visible sign. The only reliable way to know is to watch where the query actually comes out.
Ask a question only we can hear
The test generates a one-time, unique name for your session: a random label placed in front of a domain we control. Your browser then asks your system to look that name up.
Because the name has never existed before, it cannot be sitting in any cache. To answer it, the lookup has to travel all the way to our server. Whatever resolver makes that final request reveals its own public address to us along the way.
Watch at the source
When that query reaches our server, it is read the instant it arrives. Two things are pulled from it: the address of the resolver that actually asked, and the unique label from the name, so we know the query belongs to your test and not someone else's.
That pairing is held for a few minutes. Your browser then asks us which resolvers showed up for your session, and the page shows you the result.
Why the lookup has to reach us
The test name lives in its own zone, leak.dnsdoh.art, that is delegated to a nameserver we run. Delegation is the ordinary way the DNS hands responsibility for one branch of the tree to a specific server.
leak.dnsdoh.art. NS ns.leak.dnsdoh.art. ns.leak.dnsdoh.art. A 194.180.189.33
Because that branch is delegated to our own nameserver, every name ending in .leak.dnsdoh.art is answered by the machine at 194.180.189.33 and nowhere else. No cache and no third party can stand in for it.
When your resolver meets a name it has never seen, it cannot take a shortcut. It walks the chain from the root down to our nameserver and sends the final question to us directly. The source address on that question is the resolver itself, and that address is what we record. The unique label at the front of the name tells us the query belongs to your test and not someone else's.
We read each query the moment it arrives, compare the name without regard to letter case (resolvers deliberately randomise it), and ignore anything coming from a private or local address. The resolver address and your session label are kept together for a few minutes, then they expire. Your browser polls a small endpoint that returns the addresses seen for your session, and the page groups and names them.
A single test sends several unique names, not just one. Some providers spread their lookups across many machines, so asking more than once lets the whole pool show up instead of a single address.
Why this approach is honest
Reality, not settings
It sees the resolver that did the work, not the one your configuration claims.
Catches interception
Some networks quietly redirect DNS and answer it themselves. A forced fresh lookup makes that show up as an unexpected address.
Per-session, temporary
Each test uses its own throwaway name, and the captured addresses are kept only briefly before they expire.
What it does not do
It records the addresses of the resolvers that queried the test domain, for a few minutes, to show you the result. It does not log your browsing history, and a resolver's address is not your home address unless your device resolves DNS itself.
See your own result
The result is a direct measurement: the servers that answered for you, captured at the moment they asked.
Run the DNS leak test