# fingerprint.com demo not loading through a proxy

> Through one residential exit the FingerprintJS demo hung; from the same Mac with no proxy it loaded. Our runner blamed itself. The exit was why.

Source: https://mosaicbrowser.com/blog/fingerprint-demo-not-loading

## fingerprint.com wouldn't load through our proxy, and that was a result

Through one residential exit the FingerprintJS demo hung; from the same Mac with no proxy it loaded. Our runner blamed itself. The exit was why.

![1 of 49: One row of 49 that would not load, beside a screenshot: the Mosaic sidebar with profiles running, each with its own window](https://mosaicbrowser.com/covers/fingerprint-demo-not-loading.webp)

When the fingerprint.com demo will not load through a proxy and loads fine without one, the demo is telling you about the proxy's exit address. We met that exact case in a run of our detection catalogue: 48 of 49 detectors answered through one residential exit, and the FingerprintJS demo hung until our runner gave up. From the same Mac with no proxy in the path, it answered `200`. Our runner then reported the hang as a bug in our own code, which it was not, and fixing that classification is most of this story.

## Why the fingerprint.com demo does not load

There are two common reasons, and they look the same from the address bar.

The first is on your side of the connection. The demo works by running a fingerprinting script and sending what it collects to Fingerprint's servers. Content blockers and privacy browsers are built to stop exactly that kind of script, so with one switched on the page can sit half-drawn with no result.

The second is on the far side. A site can decline to serve an address it does not trust, and companies that sell visitor identification have every reason to know which addresses belong to proxy pools. A refusal can arrive as an error page, or as nothing at all, which is the form that wastes the most time.

The test that tells them apart takes a minute. Open the page from the same computer with no proxy and no blocker. If it loads there and not through the exit, stop looking at the browser.

## What our run showed

The run ended with one line we did not like:

```
1 of 49 tests ended in an exception from this script:
  1x  timeout Page.navigate   (fingerprintjs)

```

Forty-eight rows had just been read through the same browser on the same exit, so the browser was alive and the network path worked. The FingerprintJS demo answered `200` when the Mac asked for it directly and refused the tunnel when the request came from the proxy. That residential address was one several vendors already flagged, and a second detector, incolumitas, was unreachable on it too in three rounds out of three; the fuller account of that exit is in [the residential IP several detectors already knew](https://mosaicbrowser.com/blog/residential-ip-detected-as-proxy).

So the honest status for the row was `unreachable`: the site served nothing through this exit, and nothing about the profile was measured. What the runner wrote was `error`.

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Machines that exist](https://mosaicbrowser.com/features/real-fingerprints)

## Four statuses that mean different things

Our runner keeps the outcomes of a test apart because they point at different people.

```
unreachable   the site did not serve a page        the site's problem
unread        a page loaded, the extractor failed  our extractor's problem
manual        a verdict a person still has to read work we owe
error         an exception out of the runner       our bug, and the run exits non-zero

```

The first three are honest results and none of them should stop a run. `error` is different on purpose. It is the one status that says "this repository is broken", so a run that contains one ends with a failing exit code. A timeout caught by the catch-all block had landed there, and a blocked exit was reported as a defect in our code.

## How the runner tells the site from itself

The runner already tracked the thing that separates the two cases. Its connection to the browser's DevTools socket has a `gone()` check, used one level up for the case where the browser itself dies mid-run. When that socket closes, every pending call times out for the same reason, and that genuinely is ours.

So the rule became: a `Page.navigate` or `Page.enable` timeout with the socket still open is the site not answering through this exit, and it is filed as `unreachable` with that sentence in the detail. With the socket closed it stays `error`.

We proved it in both directions with a temporary catalogue row pointing at `192.0.2.1`. That address is in TEST-NET-1, a range reserved for documentation, and packets to it are dropped silently, so a navigation hangs rather than being refused:

```
with the fix       unreachable: "timeout Page.navigate, the browser is
                   alive and other sites answered, so this is the site
                   not responding through the exit this profile browses from."
with it reverted   error: "timeout Page.navigate"

```

One detail is worth keeping. The fault only reproduced on an unproxied profile. Through a proxy, the gateway refuses `192.0.2.1` at once and the row takes the `ERR_TUNNEL_CONNECTION_FAILED` path, which was already filed correctly. A fault that only appears in one of two configurations is easy to miss with one test run.

## When several sites fail together

One unreachable row is usually the site and the exit. Several at once are usually the proxy. Another run came back with eight `unreachable` rows, all `ERR_TUNNEL_CONNECTION_FAILED` or `ERR_ABORTED`, scattered through its second half. The proxy's sticky session aged out partway through a run that takes about a hundred minutes, and the gateway started refusing the stale token. Now three or more transport failures in one run are reported as one fact about the proxy, with the advice to re-check it, not as eight facts about eight sites.

## Not a verdict about the browser

A detector that would not load has not graded anything. We never count `unreachable` as a pass, and we never count it as a fail either. A demo answering one address and not another is a statement about the address, so the next step is to move the address and nothing else, then run the row again on its own.

That is also the rule for controls. A comparison browser has to browse from the same exit as the profile, or it compares two countries as well as two browsers. Which browser should be the control is a separate question, answered in [the control that settles "is it our patches?"](https://mosaicbrowser.com/blog/the-control-is-googles-build). A page that does load and passes is its own measurement with two halves, and [a FingerprintJS pass has two halves](https://mosaicbrowser.com/blog/fingerprintjs-visitor-id-two-halves) is what we read off it once it renders. And if a measurement seems to arrive before you started it, [Chrome opens connections before your test starts](https://mosaicbrowser.com/blog/chrome-preconnects-before-you-measure).

## Questions

### Why does the fingerprint.com demo not load?

The common causes are a content blocker or privacy browser stopping the demo's script, or a proxy exit the site will not serve. Load the page with no proxy and no blocker from the same computer; if it works there and not through the exit, the exit is the cause.

### Does a demo that will not load mean my browser was detected?

No. A page that served nothing measured nothing, so it is neither a pass nor a fail. In our runs the same site refused one residential exit three rounds out of three while answering the same machine directly.

### How do I test whether my proxy exit is the problem?

Change one thing at a time. Keep the browser and profile fixed and move only the exit, for example by minting a new sticky session. If the page loads on the new session, the old address was the problem.

### What does 'unreachable' mean in Mosaic's detection tests?

The site did not serve a page, so nothing about the profile was read. It is kept apart from pass, fail and error, and it never counts as a pass.

## Related

[The residential IP several detectors already knew](https://mosaicbrowser.com/blog/residential-ip-detected-as-proxy): A residential proxy can be detected as a proxy because it is one. On one Wichita exit, FingerprintJS and incolumitas never loaded in three rounds.

[A FingerprintJS pass has two halves](https://mosaicbrowser.com/blog/fingerprintjs-visitor-id-two-halves): A FingerprintJS visitor ID should differ per profile and hold across launches of one. Colliding ids link profiles; ids that change flag a spoofer.

[The control that settles "is it our patches?"](https://mosaicbrowser.com/blog/the-control-is-googles-build): Unpatched Chrome for Testing got the same IPHey verdict as our engine, so our patches were not the cause. Its voice list still differs from Chrome's.

[Chrome opens connections before your test starts](https://mosaicbrowser.com/blog/chrome-preconnects-before-you-measure): We counted 1, 0 and 0 CONNECTs in three launches and thought Chrome was bypassing the proxy for HTTPS. Our counter was reset after Chrome had started.

[The RTT client hint, read off the wire](https://mosaicbrowser.com/blog/rtt-on-the-wire): ECT, RTT and Downlink headers behind a proxy, measured: a claimed round trip moved JavaScript to 300 and left the RTT header at 50. So we claim neither.

[Same IPHey score, opposite reasons](https://mosaicbrowser.com/blog/iphey-same-score-different-signal): IPHey Unreliable on a normal Chrome is usually the exit. Our profile and a stock Chrome both got MX 90, for a browser signal and a location signal.

[A profile in Austria claimed New York](https://mosaicbrowser.com/blog/austria-claimed-new-york): Browser location does not match IP: a no-proxy profile made in Austria claimed New York. One failed lookup was never retried, and a table filled the gap.

[Why IPHey's location card can be greener on a profile than on Chrome](https://mosaicbrowser.com/blog/iphey-location-card): On one US exit in one minute, stock Chrome got IPHey's masked or inconsistent location data and our profile got green. The difference was the timezone.

## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per profile. Free holds 3 profiles. Pro is $49 a month for any number.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
