What Causes Error Results in the Holehe Module and How to Debug Them

Holehe reports error results when the asynchronous function checking a specific service raises an exception, which launch_module in holehe/core.py catches and converts to "error": True in the output.

Holehe is an open-source OSINT tool for checking if an email address is registered on various websites. Understanding why some services return errors—and how to troubleshoot them—is essential for accurate investigations and maintaining reliable results. This guide explains the root causes of error results in Holehe and provides actionable debugging techniques based on the megadose/holehe source code.

How Holehe Handles Errors Internally

The launch_module Exception Catcher

Every service check in Holehe flows through the launch_module helper function located in holehe/core.py. This function wraps each module execution in a try/except block that silently catches all exceptions and converts them to error results.

async def launch_module(module, email, client, out):
    try:
        await module(email, client, out)
    except Exception:
        name = str(module).split('<function ')[1].split(' ')[0]
        out.append({
            "name": name,
            "domain": data[name],
            "rateLimit": False,
            "error": True,          # ← error flag set here

            "exists": False,
            "emailrecovery": None,
            "phoneNumber": None,
            "others": None
        })

When any exception bubbles up from a module, the code extracts the function name and appends a standardized dictionary with "error": True. This design ensures that one failing module doesn't crash the entire scan.

Visual Error Indicators in Output

The print_result function (also in holehe/core.py) formats error entries with a red [!] prefix for terminal visibility:

elif "error" in results.keys() and results["error"] and args.onlyused == False:
    websiteprint = print_color("[!] " + results["domain"] + toprint, "red", args)

Seeing [!] next to a domain means that module encountered an unhandled exception during execution.

Common Root Causes of Error Results

  • DNS resolution failures when a service domain is unreachable
  • Connection refused or reset errors
  • HTTP 429 responses (rate limiting) that modules don't explicitly handle
  • SSL/TLS certificate problems on older Python versions

Unexpected Response Formats

Website changes frequently break Holehe modules. Common parsing failures include:

  • KeyError when expected JSON keys are renamed or removed
  • IndexError when HTML structure changes and selectors return empty lists
  • AttributeError when attempting to access properties on NoneType objects

Timeout Exceedances

Holehe uses a default 10-second timeout (configurable via --timeout). Slow services or poor network conditions can trigger premature timeouts that register as errors.

Anti-Automation Blocks

Some services implement:

  • CAPTCHA challenges that return unexpected page content
  • JavaScript-rendered responses that static requests cannot parse
  • Bot detection redirects to verification flows

Debugging Error Results in Holehe: Step-by-Step Methods

Enable Internal Debugging

Set DEBUG = True in holehe/core.py (approximately line 31) to unlock verbose logging throughout the codebase:


# In holehe/core.py

DEBUG = True

This activates print statements that reveal request URLs, HTTP status codes, response headers, and intermediate parsing results. The output includes lines like:


[DEBUG] GET https://www.facebook.com/login/identify/?email=example%40example.com
[DEBUG] Response status: 200
[DEBUG] Parsing JSON …

Run a Single Module in Isolation

Isolate the failing module to see the full exception traceback without orchestration overhead:

import asyncio
import httpx

from holehe.modules.social_media.facebook import facebook

async def test():
    async with httpx.AsyncClient(timeout=30) as client:
        results = []
        await facebook('test@example.com', client, results)
        print(results)

asyncio.run(test())

This approach surfaces the exact line number and exception type causing the failure.

Increase the Request Timeout

Use --timeout 30 or higher when launching Holehe to eliminate false-positive errors from slow services:

holehe --timeout 30 example@example.com

Some international services require 20-30 seconds for complete response cycles.

Inspect Raw HTTP Responses

Modify a module temporarily to print response data before parsing:

async def facebook(email, client, out):
    response = await client.get(
        f"https://facebook.com/login/identify/?email={email}"
    )
    print(f"Status: {response.status_code}")
    print(f"Body preview: {response.text[:500]}")
    # ... existing parsing logic

This reveals whether the service returned an error page, redirect, or changed API format.

Extract the errorMessage Field

Some modules populate results["others"]["errorMessage"] with additional context. Check if the verbose output contains more specific information beyond the generic error flag.

Examine the Module Source Code

Open the specific module file under holehe/modules/ that corresponds to the failing domain. For example:

Most modules follow a consistent pattern: HTTP request → response validation → data extraction → result appending. Look for brittle selectors or hardcoded API endpoints that may have changed.

Update to the Latest Version

Website changes are constantly patched. Update Holehe via:

holehe --check-update

# or

pip install -U holehe

The megadose/holehe repository receives frequent updates to fix modules broken by third-party API changes.

Practical Code Examples

Basic Execution with Error Observation

holehe example@example.com

Sample output showing error results:


[+] twitter.com
[-] facebook.com
[!] instagram.com Error message: Request timeout

The [!] prefix indicates instagram raised an exception during processing.

Debugging with Verbose Python Execution

PYTHONVERBOSE=1 holehe example@example.com 2>&1 | grep -i error

This surfaces low-level Python import and execution details when environment-level issues are suspected.

Programmatic Error Handling

import asyncio
from holehe.core import launch_module
from holehe.modules.shopping.amazon import amazon
import httpx

async def safe_check():
    async with httpx.AsyncClient() as client:
        results = []
        try:
            await launch_module(amazon, "test@example.com", client, results)
        except Exception as e:
            print(f"Uncaught exception: {type(e).__name__}: {e}")
        
        for r in results:
            if r.get("error"):
                print(f"Service {r['name']} failed: {r}")

asyncio.run(safe_check())

Key Source Files for Error Investigation

File Purpose Critical Components
holehe/core.py Module orchestration and error handling launch_module(), print_result(), DEBUG flag
holehe/modules/*/*.py Individual service checkers Module-specific request logic and parsing
holehe/localuseragent.py User-Agent rotation Missing or outdated headers can cause blocks
holehe/instruments.py Progress visualization TrioProgress for monitoring execution flow

Summary

  • Error results originate from unhandled exceptions in individual service modules, caught by launch_module in holehe/core.py and converted to "error": True flags
  • Network issues, parsing failures, timeouts, and anti-bot measures are the primary categories of root causes
  • Debug effectively by enabling DEBUG = True, running modules in isolation, increasing timeouts, and inspecting raw responses
  • Maintain accuracy by regularly updating Holehe and inspecting module source code when services change their implementations

Frequently Asked Questions

How can I tell if an error is temporary or permanent?

Temporary errors typically involve network timeouts or HTTP 5xx status codes. Permanent errors stem from changed APIs or removed endpoints. Run the module in isolation multiple times—if it fails consistently with the same exception type and message, the module likely needs updating. Check the megadose/holehe repository issues for confirmed breakages.

Does Holehe retry failed requests automatically?

No. The launch_module function catches exceptions on the first failure and immediately returns the error result. There is no built-in retry logic. For transient network issues, implement your own retry wrapper or increase the --timeout value to reduce timeout-related errors.

Can I suppress error results from the output?

Yes. Pass --only-used or -o when running Holehe. The print_result logic checks args.onlyused == False before displaying error entries, so this flag filters out all services that don't return a definitive "exists" or "does not exist" status—including error results.

Why does a service show error even though the website works in my browser?

Browsers execute JavaScript, handle redirects automatically, and maintain session cookies. Holehe modules use static HTTP requests without JavaScript rendering. If a service requires JavaScript or sophisticated session management, the module may fail with parsing errors or unexpected redirects that don't occur in interactive browsing.

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 →