How to Troubleshoot holehe Errors: A Complete Technical Guide
Most holehe errors stem from rate limits, network timeouts, or API changes in third-party services, and can be diagnosed by examining the "rateLimit" and "error" flags in module outputs.
holehe is an open-source OSINT tool that checks email registration status across dozens of platforms by querying service-specific modules. When something breaks, the error handling in megadose/holehe follows predictable patterns in core.py and individual module files. This guide walks you through systematic troubleshooting based on the actual source code implementation.
Understanding holehe Error Types
The tool aggregates results from asynchronous module execution via trio. Each module returns a standardized dictionary with Boolean flags indicating what went wrong.
| Output Flag | Meaning | Trigger in Code |
|---|---|---|
rateLimit: True |
HTTP 429 or similar throttling response | launch_module in core.py catches the exception and marks the result【core.py L66‑L78】 |
error: True |
Network failure, parsing exception, or unexpected response | Individual module try/except blocks catch any Exception and return this flag【twitter.py L11‑L31】 |
| CLI validation error | Malformed email input | is_email regex check aborts before modules run【core.py L94‑L105】 |
Step 1: Validate Your Email Input
The simplest failures happen before any network requests. The is_email function in core.py uses regex validation.
Run this test:
holehe not_an_email
Expected output: [-] Please enter a target email !
If your email contains special characters (like + aliases), wrap it in quotes:
holehe "user+test@example.com"
Step 2: Check Network and Proxy Connectivity
holehe relies on httpx.AsyncClient for all HTTP operations. Firewall rules, DNS failures, or corporate proxies can silently break modules.
Quick Network Test
ping google.com
curl -I https://twitter.com
Isolate a Single Module
Create a minimal reproduction script to bypass concurrency and see raw responses:
import httpx
import asyncio
from holehe.modules.social_media.twitter import twitter
async def test():
client = httpx.AsyncClient()
out = []
await twitter("test@example.com", client, out)
print(out)
await client.aclose()
asyncio.run(test())
Interpreting the output:
"rateLimit": true→ Service is throttling your IP; wait or rotate IP"error": true→ Request failed (checkclientproxy settings)"exists": true/false→ Clean result; module is working
Step 3: Diagnose Rate Limiting Issues
holehe launches all modules concurrently via trio.open_nursery() in core.py. This aggressive parallelism triggers rate limits on many services.
Symptoms of Rate Limiting
- Multiple
[x]symbols in terminal output "rateLimit": trueappearing across many services in CSV export- Temporary ban from specific platforms
Immediate Fixes
- Wait 5–10 minutes and retry with a single target
- Rotate your IP via VPN or proxy
- Throttle concurrency by modifying
core.py
Reduce Concurrency in core.py
Edit around line 18–21 in holehe/core.py:
batch_size = 20 # Reduce from unlimited concurrency
for i in range(0, len(websites), batch_size):
batch = websites[i:i+batch_size]
for website in batch:
nursery.start_soon(launch_module, website, email, client, out)
await trio.sleep(2) # Pause between batches
This trade-off slows execution but reduces [x] occurrences on strict services like Instagram or LinkedIn.
Step 4: Debug Individual Module Failures
Each service module follows this error-handling pattern:
try:
req = await client.get("https://api.service.com/endpoint", headers=headers)
# Parse JSON or HTML response
data = req.json()
# Extract registration status...
except Exception:
out.append({
"name": name,
"domain": domain,
"rateLimit": True, # Conservative default
"error": True,
"exists": False,
# ...
})
The generic except Exception masks the actual failure reason. To expose it:
Add Debug Printing to Any Module
Edit holehe/modules/social_media/twitter.py (or any failing module):
except Exception as e:
print(f"[DEBUG] {name} module error: {type(e).__name__}: {e}")
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": True,
"exists": False,
"emailrecovery": None,
"phoneNumber": None,
"others": None
})
Common exception types you'll see:
| Exception | Cause | Fix |
|---|---|---|
JSONDecodeError |
API returned HTML (blocked) or changed JSON structure | Check service status; update module parsing |
httpx.ConnectError |
DNS failure or firewall block | Verify network; configure proxy |
httpx.TimeoutException |
Slow response or dead endpoint | Increase timeout= in AsyncClient |
KeyError |
Expected JSON key missing | Module needs update for API change |
Step 5: Update Dependencies and Codebase
Upgrade Python Packages
holehe depends on httpx, trio, termcolor, and bs4. Version mismatches cause subtle failures:
pip install --upgrade httpx trio beautifulsoup4 termcolor
Verify httpx supports the AsyncClient API used throughout modules.
Pull Latest Repository Changes
Third-party services frequently change endpoints. The megadose/holehe repository is actively maintained with module fixes:
cd /path/to/holehe
git pull origin master
git log --oneline -10 # Review recent fixes
Check if your failing module appears in recent commits.
Step 6: Enable Verbose Logging and Export Results
CSV Export for Bulk Analysis
holehe target@example.com --csv
This creates holehe_<timestamp>_target@example.com_results.csv with columns for every flag. Sort by error or rateLimit to identify problematic services.
Enable Debug Mode in core.py
Uncomment or add at line 31 in holehe/core.py:
DEBUG = True
# Add throughout for tracing:
if DEBUG:
print(f"[DEBUG] Launching {website.__name__} for {email}")
Re-run to see internal state including request URLs and raw response snippets.
Key Source Files for Troubleshooting
| File | Purpose | Critical Sections |
|---|---|---|
holehe/core.py |
CLI entry point, module orchestration, result formatting | is_email validation【L94‑L105】, launch_module exception handler【L66‑L78】, trio nursery setup |
holehe/instruments.py |
Progress bar updates during async execution | TrioProgress class hooks into trio task completion |
holehe/modules/ |
Service-specific implementations | Each module's try/except block around HTTP requests and JSON parsing |
holehe/localuseragent.py |
Static user-agent rotation | Used by modules to mimic browser traffic |
Summary
- Validate input first — malformed emails fail fast in
is_emailbefore any network calls - Check
rateLimitanderrorflags in output to classify failure type - Isolate with single-module tests using
httpx.AsyncClientdirectly - Throttle concurrency in
core.pywhen hitting widespread rate limits - Add debug prints to
except Exceptionblocks to expose hidden exceptions - Keep dependencies and code updated — API changes require fresh module code
- Export to CSV for systematic analysis of which services are failing
Frequently Asked Questions
What does [x] mean in holehe output?
The [x] symbol indicates a rate-limited request. As implemented in core.py's launch_module function, when a module receives HTTP 429 or similar throttling response, the exception is caught and the result is marked with "rateLimit": True【core.py L66‑L78】. Wait several minutes or use a different IP address, then retry.
How do I fix "error": true for a specific service?
This generic flag usually means network failure or API change. Edit the module file in holehe/modules/ to add a print(e) statement inside the except Exception block, then re-run. Common causes include JSONDecodeError (service returning HTML instead of JSON), ConnectError (network blocking), or KeyError (API response structure changed).
Can I use holehe with a proxy?
Yes. The httpx.AsyncClient used throughout holehe supports proxy configuration. When testing single modules, instantiate client = httpx.AsyncClient(proxies="http://proxy:port"). For full CLI usage, set environment variables HTTP_PROXY and HTTPS_PROXY which httpx reads automatically.
Why do most services show errors after a fresh install?
Likely missing dependencies or outdated modules. Run pip install --upgrade httpx trio beautifulsoup4 termcolor, then git pull the latest repository. The check_update function in core.py warns about stale versions, but manual updates ensure compatibility.
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 →