subfinder is a fast, passive-only subdomain discovery tool developed by ProjectDiscovery (the team behind nuclei, httpx, and naabu). It is written in Go and designed for speed and simplicity — it queries dozens of passive sources (Certificate Transparency logs, public DNS datasets, search engines, and third-party APIs) without ever sending a single packet directly to the target’s own infrastructure, making it extremely stealthy. Subfinder is often used as the first step in ProjectDiscovery’s broader recon pipeline (subfinder → httpx → nuclei).
Installation
# Kali/Debian (pre-installed, or reinstall)
sudo apt update && sudo apt install subfinder -y
# Via Go
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
# Via Docker
docker pull projectdiscovery/subfinder
Verify installation:
subfinder -version
Syntax
subfinder [OPTIONS]
Command-Line Options
| Flag | Description |
|---|---|
-d, -domain DOMAIN | Target domain(s), comma separated |
-dL, -list FILE | File containing a list of domains |
-o, -output FILE | Write output to a file |
-oJ, -json | Output results in JSON format |
-oD, -output-dir DIR | Write results per-domain into a directory |
-all | Use all available data sources (including slower ones) |
-sources | List all available/configured data sources |
-es, -exclude-sources SOURCE | Exclude specific sources from the scan |
-recursive | Enumerate recursively (nested subdomains) using known patterns |
-nW, -active | Filter results to only actively-resolvable hosts |
-r, -resolvers FILE | Custom list of resolvers for resolving discovered hosts |
-t, -threads NUM | Number of concurrent threads |
-timeout SEC | Timeout in seconds per source request |
-max-time MIN | Maximum enumeration time in minutes |
-v, -verbose | Verbose output |
-silent | Show only subdomain results, no banners/logs |
-nc, -no-color | Disable colored output |
-stats | Print enumeration statistics at the end |
-pc, -provider-config FILE | Custom provider config file (API keys) |
-config FILE | Flag config file |
-rl, -rate-limit NUM | Maximum requests per second |
-ip | Include host IP addresses in output |
-cs, -collect-sources | Show which source found each subdomain |
Basic Usage
subfinder -d example.com
Expected output:
_ __ _ _S3 ___
____ _| |_ ___ _| |___ ___ ___
| _| | . | -_| . | _| . | _|
|___|___|___|___|_|_|_| |___|_|
v2.6.6
www.example.com
mail.example.com
dev.example.com
[INF] Found 3 subdomains for example.com in 4 seconds 271 milliseconds
Practical Examples
Example 1 — Basic passive enumeration
subfinder -d example.com -silent
www.example.com
mail.example.com
dev.example.com
Example 2 — Save results to a file
subfinder -d example.com -o subs.txt -silent
[+] Results saved to subs.txt
Example 3 — Enumerate multiple domains from a list
subfinder -dL domains.txt -silent
www.example.com
api.example.org
mail.example.org
Example 4 — JSON output for scripting/parsing
subfinder -d example.com -oJ -silent
{"host":"www.example.com","input":"example.com","source":"crtsh"}
{"host":"mail.example.com","input":"example.com","source":"virustotal"}
Example 5 — Show source that discovered each subdomain
subfinder -d example.com -collect-sources -silent
www.example.com,crtsh
dev.example.com,alienvault
Example 6 — Use all available sources (slower but more thorough)
subfinder -d example.com -all -silent
www.example.com
dev.example.com
staging.example.com
legacy-portal.example.com
Example 7 — Recursive enumeration
subfinder -d example.com -recursive -silent
www.example.com
api.dev.example.com
v2.api.dev.example.com
Example 8 — Filter to only actively resolvable hosts
subfinder -d example.com -nW -silent
www.example.com
mail.example.com
Example 9 — List all configured passive sources
subfinder -sources
Current list of enabled sources:
alienvault
anubis
bevigil
binaryedge
bufferover
c99
censys
certspotter
chaos
crtsh
digitorus
dnsdb
dnsdumpster
fofa
fullhunt
github
hackertarget
hunter
intelx
passivetotal
quake
robtex
securitytrails
shodan
threatbook
virustotal
waybackarchive
whoisxmlapi
zoomeyeapi
Example 10 — Chaining subfinder into httpx for live host checks
subfinder -d example.com -silent | httpx -silent -status-code
https://www.example.com [200]
https://mail.example.com [401]
Common Use Cases
- The default first step in a modern bug bounty recon pipeline (
subfinder | httpx | nuclei). - Fast, passive subdomain discovery when stealth is a priority and active brute forcing is out of scope.
- Continuous/scheduled scanning to detect newly registered subdomains for a monitored target.
- Feeding subdomain lists into port scanners (
naabu), HTTP probers (httpx), or vulnerability scanners (nuclei) as part of an automated pipeline.
Automation with Bash
Full ProjectDiscovery-style recon chain:
#!/bin/bash
# subfinder_chain.sh
DOMAIN=$1
subfinder -d "$DOMAIN" -silent -o subs.txt
httpx -l subs.txt -silent -status-code -title -o live_hosts.txt
echo "[+] Live hosts saved to live_hosts.txt"
cat live_hosts.txt
Scheduled diff-based monitoring (cron-friendly):
#!/bin/bash
# subfinder_monitor.sh
DOMAIN=$1
DATE=$(date +%F)
subfinder -d "$DOMAIN" -silent -o "subs_${DATE}.txt"
PREV=$(ls -t subs_*.txt 2>/dev/null | sed -n 2p)
if [ -n "$PREV" ]; then
NEW=$(comm -13 <(sort "$PREV") <(sort "subs_${DATE}.txt"))
if [ -n "$NEW" ]; then
echo "[+] New subdomains found for $DOMAIN:"
echo "$NEW"
fi
fi
Tips and Best Practices
- Configure
~/.config/subfinder/provider-config.yamlwith API keys for premium sources (SecurityTrails, Censys, Shodan, VirusTotal) — result quality improves dramatically over the free/unauthenticated tier. - Use
-silentin all scripts/pipelines to get clean output with no banner noise. - Pair Subfinder with
httpximmediately after enumeration to filter down to only live, in-scope hosts. - Use
-recursiveonly on domains where you expect deeply nested subdomains (e.g., large SaaS companies); it adds scan time with diminishing returns on smaller targets. - Rate-limit (
-rl) your scans when working against sources you have limited free-tier API quota for, to avoid burning through your daily limit.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Very few subdomains returned | No API keys configured — Subfinder relying only on free/unauthenticated sources | Add API keys to provider-config.yaml for significantly better coverage |
[WRN] source timeout messages | A specific data source is slow/unreachable | Ignore isolated warnings; use -es to exclude a consistently failing source |
| Duplicate results across runs | Normal — Subfinder does not deduplicate against historical scans by default | Pipe through sort -u or maintain your own diffing logic for monitoring |
| Rate-limited (HTTP 429) from a source | Free-tier API quota exceeded for that day | Wait for quota reset, or upgrade to a paid API tier for that source |
| Output includes clearly unrelated/incorrect subdomains | Some passive sources contain stale or third-party misattributed data | Cross-verify unexpected results with dig/whois before including in a report |
References
- Official GitHub repository: https://github.com/projectdiscovery/subfinder
- ProjectDiscovery documentation: https://docs.projectdiscovery.io/tools/subfinder
- Kali Linux tool page: https://www.kali.org/tools/subfinder/
