What Determines `exists: True` vs `False` in Holehe Modules: A Technical Deep Dive
A Holehe module returns exists: True when the target service explicitly confirms an email address is already registered, and exists: False when the service indicates the address is available or when the module cannot determine its status.
Holehe is an open-source reconnaissance tool by megadose that checks email address registration across hundreds of online services. Each service-specific module implements custom logic to interpret API responses, HTTP status codes, or HTML content—then distills that evidence into a single boolean exists flag. This article explains exactly how that determination happens, with concrete code examples from the repository.
The Core Pattern: Service Response → Boolean Interpretation
Every Holehe module follows a consistent structure. Located in holehe/modules/, each file implements an async function that:
- Sends a request to the service's registration or availability endpoint
- Parses the response (JSON, HTML, or status code)
- Sets
existsbased on service-specific indicators - Appends a standardized result dictionary
The exists field is never guessed—it is always derived from concrete service feedback as implemented in megadose/holehe.
How Different Services Trigger exists: True
The exact signal varies by platform. Here are the four primary patterns found in the source code.
JSON Field Extraction
Twitter queries /i/users/email_available.json and checks the "taken" field:
# holehe/modules/social_media/twitter.py
if req.json()["taken"]:
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": False,
"rateLimit": False,
"exists": True, # Email is already registered
"emailrecovery": None,
"phoneNumber": None,
"others": None,
})
else:
out.append({"exists": False, ...})
Facebook uses the inverse pattern—checking "available": false:
# holehe/modules/social_media/facebook.py
# Response indicates existing account when "available" is False
if not data.get("available", True):
exists = True
Blablacar directly forwards the service's own exists field when present:
# holehe/modules/transport/blablacar.py
if "exists" in data:
out.append({"exists": data["exists"], ...})
else:
out.append({"exists": False, ...})
HTTP Status Code Interpretation
Docker Hub treats 200 OK as confirmation of an existing account:
# holehe/modules/software/docker.py
resp = await client.get(f"https://hub.docker.com/v2/users/{email}")
if resp.status_code == 200:
out.append({"exists": True, ...})
else:
out.append({"exists": False, ...})
A 404 or any non-200 response results in exists: False.
HTML String Matching
Adobe scrapes the response body for specific error text:
# holehe/modules/software/adobe.py
if "The email address you entered is already in use" in response.text:
out.append({"exists": True, ...})
else:
out.append({"exists": False, ...})
When exists Is Forced to False
Modules intentionally set exists: False in two scenarios: when the service confirms availability, or when the check fails entirely.
Explicit Service Confirmation
If Twitter returns {"taken": false}, Facebook returns {"available": true}, or Docker returns 404, the module records exists: False—meaning the email appears unregistered.
Error and Rate-Limit Handling
Any exception (network failure, rate-limiting, unexpected response format) triggers a safe fallback. As seen across all modules in megadose/holehe:
# Generic pattern found in every module's exception handler
except Exception:
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": True, # Signals uncertainty
"exists": False, # No definitive claim
"emailrecovery": None,
"phoneNumber": None,
"others": None,
})
The rateLimit: True flag alerts users that the exists: False result is not reliable—the check simply couldn't complete.
The Result Dictionary Structure
Every module returns identical keys to holehe/core.py, which orchestrates execution and printing:
{
"name": "twitter", # Service identifier
"domain": "twitter.com", # Service domain
"method": "login", # Check method used
"frequent_rate_limit": False, # Known rate-limit behavior
"rateLimit": False, # Was this attempt rate-limited?
"exists": True, # Core finding: account exists?
"emailrecovery": None, # Recovery email (if leaked)
"phoneNumber": None, # Phone number (if leaked)
"others": None # Additional metadata
}
The exists boolean is the primary output that drives Holehe's terminal reporting and JSON export.
Module Categories and Representative Implementations
| Category | File Path | Determination Method |
|---|---|---|
| Social Media | holehe/modules/social_media/twitter.py |
JSON "taken" field |
| Social Media | holehe/modules/social_media/facebook.py |
JSON "available" field (inverted) |
| Transport | holehe/modules/transport/blablacar.py |
Forwarded "exists" from service |
| Software | holehe/modules/software/docker.py |
HTTP 200 status code |
| Software | holehe/modules/software/adobe.py |
HTML error string match |
| Core Orchestration | holehe/core.py |
Aggregates exists from all modules |
Summary
exists: Truerequires explicit service confirmation that an email is registered—via JSON field, HTTP status, or HTML indicator—not pattern matching alone.exists: Falsemeans the service reported availability or the module encountered an error and cannot make a definitive claim.- Each module is service-specific—no universal "email exists" API exists, so
megadose/holeheimplements hundreds of unique parsers. - Errors are conservative—any exception forces
exists: FalsewithrateLimit: Trueto prevent false positives.
Frequently Asked Questions
How does Holehe avoid false positives when determining exists: True?
Holehe modules only set exists: True when the target service explicitly confirms registration. For example, Twitter's API returns {"taken": true}—not merely a similar-looking response. This design prevents pattern-matching errors. When confirmation is ambiguous, modules default to exists: False.
Can exists: False mean the check failed rather than the email is available?
Yes. The exists: False value appears in two cases: when the service confirms an email is free, and when the module hits a rate-limit, network error, or unexpected response format. Check the rateLimit field—if True, the exists: False result is unreliable and should be re-checked.
Why doesn't Holehe use a single method for all services?
Each platform implements different anti-abuse protections and exposes different signals. Some return JSON (twitter.py), others expose status codes (docker.py), and many require HTML scraping (adobe.py). The modular architecture of megadose/holehe allows contributors to implement service-specific parsers without changing core logic.
What happens if a service changes its API response format?
The module will likely catch an exception and return exists: False with rateLimit: True. This conservative fallback prevents false claims. Community contributors monitor services and update modules in holehe/modules/ when formats change. Always use the latest version from the repository for accurate results.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →