# How Maigret's Self-Check Feature Verifies Database Accuracy

> Learn how Maigret's self-check feature verifies its sites database by testing usernames against expected behaviors. Discover how Maigret ensures accuracy and reliability.

- Repository: [Soxoj/maigret](https://github.com/soxoj/maigret)
- Tags: internals
- Published: 2026-04-30

---

**Maigret's self-check feature validates the sites database by programmatically testing each site's claimed and unclaimed usernames against expected behaviors, automatically disabling sites that fail verification and clearing `unchecked` tags from those that pass.**

Maigret, the open-source username enumeration tool maintained at soxoj/maigret, relies on an extensive database of site definitions that require constant validation to remain accurate against evolving platform APIs. The **self-check feature** serves as an automated quality assurance mechanism, probing each configured site to confirm that detection patterns still match actual platform behaviors. This verification process ensures that false positives and broken detections are identified before they propagate to scan results.

## How the Self-Check Mechanism Works

The verification logic resides primarily in [`maigret/checking.py`](https://github.com/soxoj/maigret/blob/main/maigret/checking.py) and operates through three distinct stages: site selection, controlled username lookups, and database state management.

### Site Selection and Task Creation

The `self_check` coroutine (starting at line 54 in [`maigret/checking.py`](https://github.com/soxoj/maigret/blob/main/maigret/checking.py)) orchestrates the validation by iterating over the complete `site_data` dictionary. It creates an asynchronous task for every site not already marked as `disabled`, specifically tracking entries carrying the `unchecked` tag so they can be cleaned up upon successful verification.

### Username Verification Logic

Each task executes `site_self_check` (defined at line 52), which performs two controlled look-ups via the core `maigret` function:

* **Claimed username check**: Queries the username stored in `site.username_claimed` and expects the result `MaigretCheckStatus.CLAIMED`.
* **Unclaimed username check**: Queries the username stored in `site.username_unclaimed` and expects the result `MaigretCheckStatus.AVAILABLE`.

The function invokes these queries with `forced=True` and `no_progressbar=True` (lines 88-100) to ensure deterministic execution without UI overhead. Any mismatch—such as a claimed username returning as available—gets recorded in the `issues` list, along with network-level failures like "Cannot connect to host" (captured around lines 21-25).

### Database Updates and Issue Handling

When `auto_disable=True` and a site generates issues, the routine sets the site's `disabled` flag and persists the change via `db.update_site(site)` (lines 89-92). Conversely, sites passing both checks have their `unchecked` tag removed and the database entry is saved again (lines 1101-1104). Optional diagnostics (`diagnose=True`) print human-readable summaries including check types and recommendations for failing sites (lines 76-86).

## Running the Self-Check

### Command-Line Usage

Invoke the verification directly from the terminal:

```bash
maigret --self-check --auto-disable

```

The CLI entry point in [`maigret/maigret.py`](https://github.com/soxoj/maigret/blob/main/maigret/maigret.py) (around line 337) parses these arguments and triggers the validation routine.

### Programmatic API Integration

Embed the validation into custom workflows using the Python API:

```python
import logging
from maigret.maigret import load_db, load_sites
from maigret.checking import self_check

logger = logging.getLogger("maigret")
db = load_db()                 # loads MaigretDatabase instance

sites = load_sites()           # loads site definitions dict

# Run verification without auto-disabling sites

result = await self_check(
    db=db,
    site_data=sites,
    logger=logger,
    auto_disable=False,
    diagnose=True,
)

print("Database needs update:", result["needs_update"])
print("Total issues found:", result["total_issues"])

```

This coroutine returns a dictionary containing `needs_update` (boolean), `results` (list), and `total_issues` (integer), allowing programmatic decisions about whether to commit database changes.

## Key Implementation Details

* **[`maigret/checking.py`](https://github.com/soxoj/maigret/blob/main/maigret/checking.py)**: Houses both `site_self_check` (per-site logic) and `self_check` (orchestration and aggregation).
* **[`maigret/maigret.py`](https://github.com/soxoj/maigret/blob/main/maigret/maigret.py)**: Parses `--self-check` CLI arguments and wires them to the checking module.
* **[`maigret/db_updater.py`](https://github.com/soxoj/maigret/blob/main/maigret/db_updater.py)**: Provides `MaigretDatabase.update_site`, which persists state changes for disabled sites or tag removals.
* **Return structure**: The `self_check` function returns `{"needs_update": <bool>, "results": [...], "total_issues": <int>}`, where `needs_update` signals whether the database file was modified during the run (lines 14-18).

## Summary

* The self-check validates sites by testing both **claimed** and **unclaimed** example usernames against expected detection statuses.
* Sites failing verification are automatically **disabled** when `auto_disable=True`, preventing them from being used in future scans.
* Successfully verified sites have their **`unchecked`** tag removed, maintaining database hygiene.
* The feature provides structured feedback through **`total_issues`** counts and **`needs_update`** flags, enabling both manual and automated database maintenance workflows.

## Frequently Asked Questions

### What triggers a site to be marked as disabled during self-check?

A site becomes disabled when the verification detects mismatches between expected and actual username statuses (e.g., a claimed username returning as available), or when network connectivity failures occur, provided the `auto_disable` parameter is set to `True`.

### How does Maigret handle sites tagged as `unchecked`?

Sites carrying the `unchecked` tag are tracked during validation; once they pass both the claimed and unclaimed username checks without issues, the tag is automatically removed and the database entry is persisted via `db.update_site(site)`.

### Can I run self-check verification without modifying the database?

Yes, set `auto_disable=False` when calling `self_check` programmatically, or omit the `--auto-disable` flag from the CLI command. This executes the verification in reporting-only mode, returning issue counts and diagnostic information without persisting any state changes to the sites database.

### What does the `needs_update` flag indicate in the self-check results?

The `needs_update` boolean signals whether the database file was modified during the check—either because sites were disabled due to verification failures, or because `unchecked` tags were cleared from sites that passed validation. This flag allows calling code to determine whether to trigger a database save operation.