Strange issue with subdomains

Here’s an apparently minor issue that is nonetheless interesting and exposes a UI issue in Tor Browser.

When using Tor Browser v12.5.1 on Debian, any subdomain is blocked on the first try: there is no error message, it simply doesn’t load (example: When retrying, the page loads, after which that subdomain works as normal, even if I change the Tor circuit. After clicking “New identity” / restarting Tor Browser, the issue repeats. It only happens for Tor Browser on GNU/Linux (Debian, at least) - not Windows, nor Android.

In the browser’s web developer tools → Network, I checked the failed GET request and looked at the Timings tab. It seems that the first connection breaks during the TLS setup phase:


Indeed, if I disable HTTPS-only mode and go to (for example), the page loads on the first try. If I use HTTP first and then HTTPS, the page loads on both tries.

So it’s a TLS-related issue. Here’s the weird thing: Tor Browser has the same JA3 fingerprint on both Linux and Android, their TLS configurations seem to be identical. So if it’s some kind of firewall issue on GitLab’s end, why doesn’t it block them both? How does it tell them apart? And how does the firewall recognize that the second visit is made from the same Tor Browser instance during the same browsing session? What gives it away? I would love to know.

Anyway, the UI issue I mentioned is that after the first connection fails, the button to view the Tor circuit is not shown. It really should be available: if a server drops the connection during the TLS handshake, it might only do that to specific exit nodes (it’s not the case here, but it could be), so users should be able to change the Tor circuit.

I was going to take this issue to GitLab support, but then I thought Tor Browser devs might want to look into it before GitLab changes anything on their end.

1 Like

I tried to figure this out and failed. I made the following observations in the process:

  • the problem goes away if I use Tor Browser without Tor
  • the problem also goes away if I make either of these changes to the TLS settings:
    • disable TLS 1.3 (security.tls.version.max = 3)
    • disable either of the three TLS 1.3 cipher suites (ex: security.tls13.aes_128_gcm_sha256).
    • disable OCSP (security.OCSP.enabled = 0)
  • however, disabling TLS 1.2 has no effect (even though this changes the browser’s TLS fingerprint significantly)
  • I tested using a specific exit node in torrc; I accessed a subdomain once, then clicked “new identity” and accessed it again. It still blocked me. So restarting the browser resets the “visit counter” even when you use the same exit node.

Within the same browsing session, could there be some TCP-level association between the first (blocked) and second (successful) visit, even if the visits are 15 minutes apart? I don’t think the connection is allowed to stay open that long. I tested using Firefox without Tor and found that TCP connections to subdomains are closed in less than 10 seconds.

I’m at a loss. Anyone?

This is still happening, but I have also encountered exceptions - sometimes (rarely) * pages do load on the first try.

I’ll list a few links, for testing: is the subdomain where I’ve encountered most exceptions.

Do Tor Browser devs keep track of what’s being posted on the forum? Should I submit this issue on Tor’s GitLab instance?

does it happen with TB13.0a2

It does.


On Mon, 2023-08-21, thorin via Tor Project Forum wrote:

does it happen with TB13.0a2

depends :slight_smile: i’ve pinged one for ya!

That’s an interesting change we could actually do.

I quickly checked if I could understand what happens behind the scenes, and I think I found a possible cause for the current behavior.
At the moment, we associate a certain stream to a circuit when it’s successful (the stream received a reply). We need this passage because Tor opens a few circuits in advance (I think to improve performances, but I don’t really know much about the daemon) and when you connect to a new first party you usually open a stream with a circuit that was already built but not used yet.
In the failure cases you brought, the stream never succeeds when associated to the failing circuits, it arrives to a DETACHED instead, then switches to another circuit, and a STREAM SENTCONNECT event is sent through the control port.
Switching from the SUCCEEDED to the SENTCONNECT event could do what you ask (not sure, I haven’t tried).
At the moment the code for the tor integration is undergoing a big refactor, I’d prefer to get that merged before doing this change.
However, we can open an issue to follow up later. Do you have a GitLab account and do you want to open one, or do you prefer me to do it?


Thanks for the reply! Alas, I don’t have deep knowledge of Tor’s innards, so I don’t understand the hypothesis you laid out. Glad to see you have one, though. :slight_smile:

Please just clear this up for me: why does this only happen on subdomains? And do you think it’s a purely local problem in TBB’s code, or do you think GitLab’s firewall distinguishes between first and second visit (if so, how)?

That’s an interesting change we could actually do.


However, we can open an issue to follow up later. Do you have a GitLab account and do you want to open one, or do you prefer me to do it?

Sounds good. I’d rather you do it, because you’re in a better position to formulate the issue in more precise terms for your fellow developers. So, please do.

There are three issues, really: explaining why this happens, fixing the UI problem and fixing the actual connection problem.

I haven’t heard back from you, so I opened the issues myself:


Sorry for not answering back, I must have marked the notification as read before following up.