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:

  1. Sends a request to the service's registration or availability endpoint
  2. Parses the response (JSON, HTML, or status code)
  3. Sets exists based on service-specific indicators
  4. 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: True requires explicit service confirmation that an email is registered—via JSON field, HTTP status, or HTML indicator—not pattern matching alone.
  • exists: False means 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/holehe implements hundreds of unique parsers.
  • Errors are conservative—any exception forces exists: False with rateLimit: True to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →