FAQ
For operators · scanning
How-toEach question opens with a one-sentence answer in bold so you can scan the FAQ in 30 seconds. Read the paragraph after it if you need the context.
Why is everything coming back as Uncertain?
Section titled “Why is everything coming back as Uncertain?”Your scan source is on a CDN blocklist — usually a datacenter IP that’s
been mass-banned. Try a residential proxy, or the browser backend for
bot-protected sites.
Datacenter IP ranges (Hetzner, OVH, Linode, AWS, …) are pre-banned by
Cloudflare, Akamai, and most major edges. From there, the cheap HTTP
path returns Uncertain(cloudflare_challenge) or Uncertain(rate_limited)
for a big chunk of the registry — not because the accounts don’t exist,
but because nobody reachable from that IP gets a working response.
Three remedies, ranked by effort:
adler --proxy socks5://USER:PASS@HOST:PORT alice # one global residential proxyadler --proxy-pool pool.toml alice # per-site geo / IP-type routingadler --browser-backend local alice # bot-protected sites via headless Chromeadler --explain alice prints the signal that flagged each verdict so
you can tell why it was inconclusive (cloudflare_challenge,
geo_unavailable, session_required, …).
For sites that systematically sit behind Cloudflare without being
pre-tagged bot-protected, automatic
escalation retries through the
browser backend on its own once --browser-backend is set.
Why does Adler report fewer Found accounts than Sherlock or Maigret?
Section titled “Why does Adler report fewer Found accounts than Sherlock or Maigret?”Because Adler verifies its NotFounds. Sherlock and Maigret return
NotFound even when the response was a Cloudflare wall — Adler reports
Uncertain(reason) instead. Check the Uncertain bucket; most of the
“missing” hits are there with a reason.
Adler’s NotFound literally means “the site returned a working response
that says this account does not exist.” Sherlock and Maigret count
“I got blocked at the first wall” the same way — that’s a false
negative, not a verdict. Once you resolve the wall (browser backend,
residential IP, sessions), the Uncertain rows flip to Found.
See Access engine for the toolkit and Site registry → Detection rate for the quantified gap.
How do I scan Instagram, X (Twitter), or Threads?
Section titled “How do I scan Instagram, X (Twitter), or Threads?”They’re tagged bot-protected — plain HTTP gets a login wall. Add
--browser-backend local (free, local Chrome) or --browser-backend browserbase (paid, residential cloud). For Instagram specifically, add
a session via --sessions for authenticated profile data.
These platforms detect every HTTP scrape and serve a login interstitial that looks identical for an existing and a missing account. The browser backend runs JS, accepts cookies, and returns the final post-render DOM — same detection signals apply, real verdict comes out.
A session supplied via --sessions sessions.toml lets you reach
authenticated-only profile data on top:
[ig]Cookie = "sessionid=...; csrftoken=..."X-IG-App-ID = "936619743392459"--proxy versus --proxy-pool — which do I want?
Section titled “--proxy versus --proxy-pool — which do I want?”--proxy routes everything through one proxy. --proxy-pool is
per-site: the registry declares “this site needs a UK residential IP”,
Adler picks a matching egress; sites without a constraint use the
default. Mix them freely.
--proxy is the brute-force lever — useful when your local network is
the problem and one residential exit fixes everything. --proxy-pool is
the precise lever — useful when specific sites need specific geos / IP
types and you don’t want to round-trip the rest of the registry
through them.
The pool TOML accepts an optional name so you can pick a subset for a
single scan from the SPA’s Advanced filters; see Access engine →
Egress pool and Web UI →
Per-scan egress subset.
A site’s signature is stale — how do I fix it?
Section titled “A site’s signature is stale — how do I fix it?”Run adler --doctor --fix --only <site>. It diffs present / absent
responses and prints a paste-ready corrected signal.
Upstream Sherlock / Maigret signatures rot — sites change their response
markup, their known_present accounts get deleted, their CDN flips.
The doctor probes a known-present user
(must resolve to Found) and a random nonsense user (must not). Sites
where both halves agree pass; the rest get the --fix treatment.
--doctor --suggest-known-present is the complementary tool — it probes
a small candidate pool (the site’s brand name plus torvalds /
octocat / admin / …) and prints a paste-ready snippet for sites
where it finds a live account.
A nightly GitHub Action runs the full doctor sweep across the registry and flags structural rot. See Site registry → Validating signatures.
Is it legal to use sock-puppet accounts with --sessions?
Section titled “Is it legal to use sock-puppet accounts with --sessions?”Adler ships nothing here — you bring the session. Whether your engagement authorises operating under a pseudonymous account against a site’s ToS is your call as an operator.
We don’t take a position on what your engagement scope authorises; that’s between you, your engagement, and the site’s ToS. What Adler does take a position on:
- Authorised pentests, bug-bounty engagements, security research with a lawful basis — fine. Adler is built for this.
- Stalking, harassment, doxxing, mass-targeting individuals — not
fine, and not what this tool is for. See
SECURITY.mdandCODE_OF_CONDUCT.mdin the repo for our ethics line.
What’s the difference between transport: browser and transport: browser*?
Section titled “What’s the difference between transport: browser and transport: browser*?”No * = browser was the primary route (the site is pre-tagged
bot-protected). * = the cheap path returned Uncertain and the
router automatically escalated to the browser.
The * suffix marks an outcome where automatic
escalation fired — the operator didn’t ask for
the browser fetch, but a cloudflare_challenge or rate_limited
response on the cheap path made the router try the browser anyway.
That’s the access engine catching the long-tail Cloudflare rollout
without you having to pre-tag every newly-walled site.
Can I turn off automatic escalation?
Section titled “Can I turn off automatic escalation?”--no-escalation disables it. --escalation-budget 0 is equivalent.
Use either when you want to benchmark the raw HTTP signals or stop a
Browserbase quota burning on surprise browser fetches.
Three common reasons to disable:
- Benchmarking the cheap path’s recall without the access engine’s lift on top — comparable to Sherlock / Maigret then.
- Cost control when running on a Browserbase quota you don’t want spent on surprise escalations.
- Strict cheap-path semantics for a CI-style gate that should only match what plain HTTP can confirm.
See Access engine → Automatic
escalation for the reason
whitelist (escalation triggers on cloudflare_challenge and
rate_limited only — operator-policy Uncertains are kept as-is).
My adler --web is on 0.0.0.0. What should I worry about?
Section titled “My adler --web is on 0.0.0.0. What should I worry about?”Anyone on your network can hit the JSON API. Proxy URLs and session
secrets aren’t exposed (/api/access returns names + countries + kinds
only), but POST /api/scan lets a stranger consume your --proxy-pool
quota and --browser-budget. Put auth in front of any non-loopback
bind.
adler --web binds to 127.0.0.1 by default. Switching to
--web-bind 0.0.0.0:9000 opens the API to your network. Adler’s API
deliberately doesn’t surface proxy credentials or session header
values — even GET /api/access only returns the (name, country, kind)
triples — but a wide-open POST /api/scan still lets a stranger
trigger scans that consume your pool quota, browser budget, and
escalation budget.
Reverse-proxy patterns that work:
- Caddy with a Basic Auth directive
- Traefik with a forward-auth middleware (e.g. Authelia / Authentik)
- nginx with
auth_basic
Adler is not built to be exposed to the open internet. See Web UI → Security notes.