Holehe Detection Limitations: Why This OSINT Tool Misses Accounts and How to Work Around It

Holehe cannot detect email-registered accounts when services use CAPTCHAs, JavaScript-dependent checks, rate-limiting, or change their response format, because it relies on simple HTTP requests to public "email availability" endpoints.

Holehe is a popular open-source OSINT tool by megadose that checks whether an email address is registered across 300+ services. According to the megadose/holehe source code, its detection method follows a uniform pattern: each module sends a single HTTP request mimicking a Firefox browser, then matches the raw text response against hardcoded keywords like "no" or "ok". This design creates specific Holehe detection limitations that security researchers and OSINT practitioners must understand.


How Holehe Detection Actually Works

The core detection logic lives in individual service modules. In holehe/modules/software/lastpass.py, the pattern is representative of all 300+ modules:

async def lastpass(email, client, out):
    headers = {...'User-Agent': random.choice(ua["browsers"]["firefox"]),...}
    params = {'check': 'avail', 'username': email}
    response = await client.get('https://lastpass.com/create_account.php',
                               params=params, headers=headers)
    if response.text == "no":               # email exists

        out.append({"exists": True, ...})
    elif response.text in ("ok","emailinvalid"):   # email not used

        out.append({"exists": False, ...})
    else:                                   # rate‑limit or unknown response

        out.append({"rateLimit": True, ...})

This simplicity enables speed and scalability but introduces significant constraints.


Critical Holehe Detection Limitations

Requires Static, Public Email-Availability Endpoints

Every module depends on a single HTTP GET or POST to an unauthenticated endpoint that returns plaintext responses. If a service hides its registration check behind JavaScript execution, dynamic rendering, or a JSON API requiring CSRF tokens, Holehe cannot interpret it. The holehe/modules/software/lastpass.py implementation at lines 28-34 demonstrates this: it directly compares response.text to fixed strings with no parsing layer for complex responses.

Fragile to Response Format Changes

Detection relies on exact string matching. In holehe/modules/software/lastpass.py lines 32-42, the module checks for "no" (account exists), "ok" or "emailinvalid" (account does not exist). Any wording change, added HTML wrapper, or redirect breaks detection and produces false negatives or positives.

Coarse Rate-Limit Handling

When a service returns a rate-limit response, Holehe's core orchestration in holehe/core.py lines 22-31 marks it as rateLimit: True and continues without retry logic. This means:

  • Temporary IP blocks hide existing accounts
  • No exponential backoff or proxy rotation occurs
  • Results may incorrectly suggest an account does not exist

No Password-Recovery Path for Many Sites

The --no-password-recovery flag disables additional verification flows. According to holehe/core.py lines 55-60, several modules including Adobe and Mail.ru are deliberately excluded when this flag is set. If a service only reveals account existence through password-reset flows, Holehe misses it entirely unless the flag is omitted.

Cannot Bypass Anti-Bot Protections

Holehe does not support:

  • CAPTCHA solving
  • Cloudflare challenge handling
  • JavaScript execution
  • Browser automation

Services protecting their registration endpoints with these mechanisms return "rate-limited" or "error" statuses regardless of actual account existence.

Generic Network Error Handling

Unexpected exceptions in holehe/core.py lines 66-78 are caught and reported as "error": True without retry logic. Transient connectivity problems, DNS failures, or TLS handshake timeouts therefore hide real results rather than triggering reattempts.

Limited to Curated Module List

Holehe only knows services with Python modules under holehe/modules/*. New platforms, URL changes, or API migrations remain invisible until manually added.

Async Concurrency Timeout Constraints

Holehe uses trio for asynchronous requests, but the default 10-second timeout (--timeout 10) in holehe/core.py lines 94-96 aborts slower services prematurely.


# Increase timeout to reduce false negatives from slow endpoints

holehe user@example.com --timeout 30

When Holehe Detection Fails: Practical Examples

Scenario Result Cause
Service adds Cloudflare to registration page "rateLimit": true Cannot execute JavaScript challenge
API response changes from "no" to "taken" "exists": false (incorrect) String match fails
Password-reset only reveals account Missed detection --no-password-recovery excludes module
5-second response time "error": true Default timeout too aggressive
CAPTCHA on email check "rateLimit": true No CAPTCHA-solving integration

Key Files Defining Detection Boundaries

  • holehe/core.py — Central orchestration, argument parsing, rate-limit and error handling (lines 21-31, 55-60, 66-78, 94-96)
  • holehe/modules/*/*.py — Individual service checks implementing the simple availability request pattern
  • holehe/localuseragent.py — Random Firefox user-agent rotation for request fingerprinting
  • holehe/instruments.py — Trio-based async progress bar and event loop implementation

Summary

Holehe's detection limitations stem from its architectural choice: fast, lightweight HTTP requests to public endpoints with plaintext response parsing. Key constraints include:

  • Endpoint dependency — No JavaScript, CAPTCHA, or dynamic API support
  • Fragile string matching — Response changes break detection
  • No retry logic — Rate limits and network errors hide results
  • Optional password-recovery — Some modules disabled by flags
  • Fixed module list — New services require manual addition
  • Timeout rigidity — Default 10s may abort legitimate checks

For services with straightforward email-availability endpoints, Holehe remains effective. For protected or complex authentication flows, expect false negatives.


Frequently Asked Questions

Why does Holehe report "rateLimit" when no rate limit exists?

Holehe uses "rateLimit": true as a catch-all for any non-matching response. According to holehe/core.py, this includes CAPTCHA pages, Cloudflare challenges, unexpected HTML, and actual rate-limit responses. The tool cannot distinguish between these cases because it lacks JavaScript execution and advanced response parsing.

Can Holehe detect accounts on services with JavaScript-based checks?

No. Holehe's modules in holehe/modules/* perform static HTTP requests only. Services that load registration checks dynamically or require browser interaction return "rateLimit" or "error" statuses. Browser automation tools like Selenium or Playwright are required for these cases.

How can I reduce false negatives from slow services?

Increase the timeout beyond the default 10 seconds: holehe user@example.com --timeout 30. The timeout parameter in holehe/core.py lines 94-96 controls how long trio waits for each async request. Values above 30 seconds reduce premature failures but slow overall execution.

Does disabling password-recovery checks improve accuracy?

No—it reduces coverage. The --no-password-recovery flag excludes modules like Adobe and Mail.ru that verify accounts through password-reset flows. Only use this flag when speed is prioritized over completeness, as documented in holehe/core.py lines 55-60.

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 →