# Understanding the Difference Between rateLimit and Error States in Holehe

> Distinguish between rateLimit and error states in Holehe module output. Understand when requests are throttled versus when module exceptions occur.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: deep-dive
- Published: 2026-08-19

---

**The `rateLimit` flag indicates that a service blocked the request due to throttling (preventing email verification), while the `error` flag signals that the module itself raised an exception during execution.**

Holehe modules return standardized dictionaries containing boolean flags that communicate the outcome of each email probe. Understanding the distinction between **`rateLimit`** and **`error`** states is essential for interpreting scan results accurately, as these flags represent fundamentally different failure modes in the megadose/holehe codebase. While both prevent determining whether an email exists on a service, they require different remediation strategies.

## Semantic Distinctions: Service Blocking vs. Client Failures

The primary difference lies in where the failure originates. **`rateLimit`** represents a **service-level** response indicating the remote server is actively throttling or blocking requests. **`error`** represents a **client-level** failure indicating the module code itself encountered an unhandled exception, network failure, or parsing error.

When **`rateLimit`** is `True`, the module successfully reached the service but received a definitive signal that the request was blocked—commonly a missing authentication token, a redirect, or a specific JSON field indicating throttling. The application renders these results with a yellow `[x]` marker to indicate the service was contacted but the inquiry was rejected.

Conversely, when **`error`** is `True`, the generic wrapper in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) caught an exception before the module could return a clean result. These entries display a red `[!]` marker, signaling that the code failed to process the response entirely, independent of the service's availability.

## How rateLimit Detection Works in Module Code

Individual service modules implement custom logic to detect when a platform enforces rate limiting. These checks vary by service but consistently set the `rateLimit` key to `True` when the response indicates throttling.

### Detecting Rate Limits in Service Responses

In [`holehe/modules/transport/blablacar.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/transport/blablacar.py), the module checks for a specific indicator in the JSON response to identify rate limiting. When the data contains a `"url"` key (indicating a redirect or error page rather than a profile), the module appends a result dictionary with `rateLimit: True`:

```python
if "url" in data.keys():
    out.append({
        "name": name,
        "domain": domain,
        "method": method,
        "frequent_rate_limit": frequent_rate_limit,
        "rateLimit": True,          # Service-level throttling detected

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

```

As shown in lines 33–38 and 62–67 of [`blablacar.py`](https://github.com/megadose/holehe/blob/main/blablacar.py), this pattern applies when the module cannot fetch a required token or when the response structure indicates a block. The `exists` field remains `False` because the module cannot definitively determine email presence when throttled.

## How Error Handling Works in the Core Wrapper

Unlike `rateLimit`, which modules set explicitly based on service responses, the **`error`** flag is injected automatically by Holehe's central orchestrator when a module crashes during execution.

### The launch_module Exception Catcher

The `launch_module` function in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) (lines 68–78) wraps every module call in a try-except block. If a module raises any exception—whether from network timeouts, HTTP parsing failures, or unexpected HTML structures—the wrapper appends a standardized error result:

```python
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,      # Explicitly not a rate limit

            "error": True,           # Indicates exception occurred

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

```

This implementation ensures that even buggy or outdated modules cannot crash the entire scan. The `rateLimit` field is explicitly set to `False` in error states to distinguish these client-side failures from service-side throttling.

## Recoverability and Retry Strategies

Understanding which flag triggered helps determine appropriate next steps:

- **Rate-limited results** (`rateLimit: True`) suggest the service is reachable but temporarily blocking the specific request pattern. Success is possible after waiting, rotating IP addresses, or modifying user-agent strings.
- **Error results** (`error: True`) typically indicate the module code requires debugging to handle updated website layouts, API changes, or unexpected response formats. Simply retrying the same request usually produces the same failure.

## Summary

- **`rateLimit`** is a service-level boolean set by individual modules when they detect throttling indicators (e.g., specific JSON fields or token failures).
- **`error`** is a client-level boolean injected by the `launch_module` wrapper in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) whenever a module raises an unhandled exception.
- Rate-limited services return yellow `[x]` markers and may succeed with different network conditions.
- Errors return red `[!]` markers and usually require code updates to the specific module.

## Frequently Asked Questions

### Can a Holehe module return both rateLimit and error set to True?

No. According to the implementation in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), when the `launch_module` wrapper catches an exception, it explicitly sets `"rateLimit": False` alongside `"error": True`. This mutual exclusivity ensures that `rateLimit` only appears when the module completed execution but detected service-side throttling, while `error` only appears when execution failed entirely.

### How do I resolve rateLimit errors in Holehe?

Rate-limit errors indicate the target service detected and blocked your request pattern. To resolve these, implement request delays between probes, rotate IP addresses using proxies, or modify the user-agent string in the client configuration. Since the module code executed successfully (it detected the block), the service itself is functional but throttling your specific traffic.

### What causes the error flag to appear in module output?

The `error` flag appears when a module raises an exception during execution, which can stem from network timeouts, DNS resolution failures, unexpected HTML structures that break parsing logic, or API endpoint changes that invalidate the module's request logic. Check the specific module code in `holehe/modules/` and compare the current website structure against the parsing logic to diagnose the root cause.

### Does rateLimit: True mean the email exists on the service?

No. When `rateLimit` is `True`, the `exists` field is simultaneously set to `False` because the module cannot obtain definitive information. The rate limit prevented the service from processing the email check, so Holehe reports that existence is unknown due to throttling, not that the email is absent.