CLI tool
projectdiscovery/dnsx avatar
projectdiscovery/dnsx

dnsx: a DNS query toolkit for resolver-driven enumeration

dnsx is a fast and multi-purpose DNS toolkit allow to run multiple DNS queries of your choice with a list of user-supplied resolvers.

2,879 stars331 forksGoMIT

At a glance

What is it?
dnsx wraps the retryabledns library in a CLI that resolves, brute-forces and filters DNS records across UDP, TCP, DoH and DoT resolvers. It is built for pipeline work, and it assumes you already know what you want to ask.
Who is it for?
Adopt dnsx if you already pipe hostnames between tools and want record-level answers with wildcard noise removed. Do not adopt it as a general-purpose resolver for application code, and do not expect the README to explain wildcard thresholds; the flag help is the documentation.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What dnsx is for, and who ends up using it

dnsx answers one question repeatedly: which of these hostnames actually exist, and what records do they carry. The README frames it as a fast and multi-purpose DNS toolkit designed for running various probes through the retryabledns library, and the feature list is explicit about A, AAAA, CNAME, PTR, NS, MX, TXT, SRV and SOA queries, resolution and brute-force modes, custom resolvers in TCP, UDP, DoH and DoT form, and automatic wildcard handling.

The audience is narrow but real. If you have a file of candidate subdomains from passive sources, or a wordlist you want to expand against one domain, dnsx is the step between collection and whatever you do next. The README's first example is exactly that shape: subfinder output piped into dnsx to keep only hostnames that resolve. Nothing in the tool is aimed at application developers who need a resolver client. There is no library-first tutorial in the README, no error-handling guide for embedding, and the documented surface is flags.

That is a deliberate position rather than a gap. dnsx reads stdin, writes stdout, and treats a list of hostnames as its unit of work. Tools that fit that shape get a lot out of it. Tools that want a callback per lookup do not.

How a dnsx run actually flows: resolvers, threads and wildcard filtering

The architecture visible from the repository is thin by design. cmd/ holds the CLI, internal/ and libs/ hold the implementation, and the heavy lifting sits in the retryabledns dependency, which is where retries and multiple transport formats come from. The go.mod file also pulls in cdncheck and asnmap, which is why the -cdn and -asn probe flags exist, and mapcidr, which is what makes comma-separated and file-based resolver input practical.

A run proceeds in stages that map onto the flag groups. Input arrives through -l for a list of subdomains or hosts, or through -d and -w for brute-force mode where a domain is expanded against a wordlist. Queries are issued according to the record-type flags, with -a as the default and -recon as the everything option covering a, aaaa, cname, ns, txt, srv, ptr, mx, soa, axfr and caa. Filtering happens after the answer comes back: -resp prints the response, -resp-only prints just the response, and -rcode narrows by DNS status code such as noerror, servfail or refused.

The wildcard machinery is the part worth understanding before you trust a result set. The README describes automatic wildcard handling as a feature and links the concept to shuffledns. The flags show two paths: -auto-wildcard detects wildcard domains for filtering, while -wd sets a domain manually and is documented as mutually exclusive with -auto-wildcard, with other flags ignored and JSON output recommended. The threshold flag -wt defaults to 5. The README does not explain what that threshold counts, so treat it as a knob to test rather than a value to assume.

Concurrency and pacing are separate controls. -threads defaults to 100, and -rate-limit defaults to -1, which the help text describes as disabled. -retry defaults to 2 and must be at least 1, and -timeout defaults to 3s. Those four numbers, not the record types, determine whether a run against a large list finishes quickly or gets you rate-limited by the resolver you pointed it at.

Installing dnsx and running a first resolution

The README states that dnsx requires go1.21 to install successfully, and gives a single install command that pulls the latest version from the module path. Note that go.mod declares go 1.25.0 for the module itself, so a toolchain at or above that version is the safer bet if you build from source.

bash
go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest

After that, confirm the binary is on your PATH and see the full flag list, which is the real documentation for this tool. The README shows the same command as the entry point to usage.

bash
dnsx -h

A first real use is resolving a list of hostnames. The README's resolving example pipes subfinder output directly into dnsx with -silent, and the output is the subset of hostnames that resolved:

bash
subfinder -silent -d hackerone.com | dnsx -silent

If you want the addresses rather than the hostnames, add -a -resp. The README's example output shows each hostname followed by its A record in brackets, with multiple lines per host when several addresses exist:

bash
subfinder -silent -d hackerone.com | dnsx -silent -a -resp

For machine-readable output, -json writes JSONL and -o writes to a file. The -ot flag takes a custom template, and the README gives the example -ot '{{host}} {{a}}'. A brute-force run swaps the input flags: -d takes the domain and -w the wordlist, both of which the help text says can be a file, comma-separated values, or stdin. If you are unsure whether your environment is set up correctly, -hc runs a diagnostic health check.

Where dnsx stops being the right tool

The clearest limitation is documented rather than implied: -stream disables the wordlist, wildcard, stats and stop/resume features. Streaming and brute-force are mutually exclusive modes, so you cannot watch a wordlist expand in real time. If your workflow depends on incremental output during a long brute-force run, dnsx will not give it to you.

The wildcard filter is the second place to be careful. -wd ignores other flags and is documented as mutually exclusive with -auto-wildcard, and the README recommends JSON output for that mode. That is a strong hint that the manual path changes the shape of what you get back. The default threshold of 5 is unexplained in the README, and the interaction between a wildcard domain and a record-type flag is not spelled out either. On a domain with aggressive wildcard DNS, filtering can remove hostnames that genuinely resolve.

There is also a scope boundary worth naming. dnsx is an enumeration and probing tool, not a validating resolver. It does not claim DNSSEC validation, and the README says nothing about caching semantics, so every run hits your resolvers fresh. If you need a resolver for production traffic, or you need to reason about cache behaviour and TTLs, this is the wrong layer. The -axfr flag also deserves caution: AXFR against a zone you do not control is a request the operator will notice, and the README gives no guidance on when it is appropriate.

Finally, the README is a flag reference more than a manual. Wildcard semantics, threshold meaning, and the exact JSONL schema are not described there. You will learn them by running the tool.

dnsx against massdns and dnsgen-style workflows

The obvious comparison is massdns, the long-standing bulk resolver that many enumeration pipelines were built around. The difference is in where the logic lives. massdns is a resolver: you feed it names and resolvers, and it produces resolution results at high volume with its own output format. dnsx wraps retryabledns and adds the layer above resolution: record-type selection, response filtering by status code, CDN and ASN annotation, JSONL output, output templates, and wildcard filtering. If your pipeline already parses massdns output and you only need raw resolution, dnsx does not replace that. If you want the filtering and the record types in the same binary, massdns does not offer them.

The second comparison is within the same family. shuffledns, which the README references when describing wildcard filtering, is a brute-forcing tool built around the same resolver library. dnsx's -d and -w flags overlap with that ground, but dnsx also resolves arbitrary lists and queries specific record types, so it occupies a broader position. Choosing between them is mostly about whether the input is a wordlist or a list of already-known hostnames.

A third pattern worth noting is composition with dnsgen-style permutation tools. dnsx does not generate candidate names; it consumes them. The README's examples all assume something upstream produced the list. That is a design choice, and it means dnsx slots into a pipeline rather than replacing one.

Maintenance, licence and what an upgrade costs you

The repository is not archived. The last push was on 2026-09-21, and the most recent release is v1.3.1 from 2026-08-31, following v1.3.0 on 2026-07-16 and v1.2.3 on 2025-12-10. The gap between v1.2.3 and v1.3.0 is roughly seven months, and the two 1.3.x releases are six weeks apart. That pattern suggests bursts of work rather than a steady cadence, which is worth knowing if you pin versions in CI.

Upgrade cost is low on the surface and moderate underneath. There is a self-update flag, -up, and an automatic update check that -duc disables. In a controlled environment you will want -duc set, because a tool that phones home during a scan is a surprise in an air-gapped pipeline. The dependency list is the real cost: retryabledns, cdncheck, asnmap, mapcidr, goflags and utils all move independently, and the ASN and CDN annotations depend on data shipped with those libraries. A dnsx upgrade can change what -asn or -cdn reports without any change to dnsx's own flags.

The licence is MIT, per the LICENSE.md file in the repository root. MIT is permissive and places few obligations on how you redistribute or embed the binary, but the dependencies carry their own licences, and the README and LICENSE.md do not enumerate them. If you vendor dnsx into a product, check go.mod against your own policy rather than assuming the top-level MIT covers everything. That is a packaging question, not a legal opinion.

Editorial conclusion

Adopt dnsx if you already pipe hostnames between tools and want record-level answers with wildcard noise removed. Do not adopt it as a general-purpose resolver for application code, and do not expect the README to explain wildcard thresholds; the flag help is the documentation. Before trusting output in a report, run the same list twice with and without -auto-wildcard and diff the results, because the wildcard filter is the part most likely to change what you see.

Frequently asked questions

What does dnsx do?

dnsx is a DNS toolkit for running queries from the command line. It resolves lists of hostnames, brute-forces domains against wordlists, supports A, AAAA, CNAME, PTR, NS, MX, TXT, SRV and SOA records, accepts custom resolvers over TCP, UDP, DoH and DoT, and filters wildcard results.

How do I install dnsx?

The README states that dnsx requires go1.21 and gives one command: go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest. The repository also ships a Dockerfile that builds the binary and copies it to /usr/local/bin/, with dnsx as the entrypoint.

Can dnsx brute-force subdomains?

Yes. The -d flag takes a domain and -w takes a wordlist, and the help text says both can be a file, comma-separated values, or stdin. Note that -stream disables the wordlist, wildcard, stats and stop/resume features, so brute-force and streaming do not combine.

How does dnsx handle wildcard DNS?

The README lists automatic wildcard handling as a feature. The -auto-wildcard flag detects wildcard domains for filtering, and -wd sets a domain manually, which the help text says is mutually exclusive with -auto-wildcard and causes other flags to be ignored. The -wt threshold defaults to 5, but the README does not explain what it counts.

Can dnsx write JSON output?

Yes. The -j flag writes output in JSONL format, and -omit-raw removes the raw DNS response from that output. The -o flag writes to a file instead of stdout, and -ot applies a custom template such as '{{host}} {{a}}'.

Official sources

  1. License: MIT
  2. projectdiscovery/dnsx on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/projectdiscovery-dnsx.svg)](https://hysenlabs.com/projects/projectdiscovery-dnsx)