What is TLS Fingerprint?
A TLS fingerprint is an identifier derived from the ClientHello a client sends when it opens an HTTPS connection: the TLS version offered, the ordered cipher suite list, the extension list, supported elliptic curves and signature algorithms. JA3 and JA4 are the common encodings of it. Different HTTP clients and browsers produce visibly different values.
The ClientHello is the first message of a TLS handshake and it travels in the clear, before any key exchange completes, so anything on the path can read it. It carries the highest TLS version the client offers, an ordered list of cipher suites, an ordered list of extensions, the supported elliptic curves and signature algorithms, and usually an ALPN list and the SNI hostname. A TLS library emits those lists in an order its authors fixed. OpenSSL, BoringSSL, Go's crypto/tls and Java's JSSE each produce a recognisably different handshake.
Detection systems encode that structure and compare it against the HTTP request riding inside the tunnel. A request whose User-Agent claims desktop Chrome, sent by a Python client whose handshake is plain OpenSSL, is a contradiction no real browser produces. The check costs a CDN almost nothing and runs before your first byte of application data, which explains 403s that arrive with no rate limit and no CAPTCHA behind them. HTTP/2 SETTINGS values and header order get compared the same way.
Browsers move. Chrome ships GREASE values (RFC 8701) in its cipher and extension lists to keep middleboxes tolerant of unknown code points, and it now randomises extension order per connection. Fingerprint formats deal with that by discarding GREASE code points and, in JA4's case, sorting the lists before hashing. Clients that want to pass as a browser copy the whole structure rather than one field: curl-impersonate rebuilds curl against a browser TLS stack, and uTLS lets Go programs replay a chosen browser's ClientHello byte for byte.
A forwarding proxy does not change any of this. When a client opens an HTTPS connection through HTTP CONNECT or SOCKS5, the proxy moves bytes and your own ClientHello reaches the server untouched, so the fingerprint stays yours while only the source IP changes. The exception is a proxy that terminates TLS and re-originates it, which substitutes its own handshake and breaks certificate pinning along the way. Rotating exit IPs will not fix a client that fingerprints as a scripting library.
Where you meet it
You meet TLS fingerprinting when the same request works from a browser and fails from your script with identical headers on the same proxy. Copying cookies and User-Agent strings does not help, because the block happened during the handshake. It forces a choice of HTTP client: a plain requests or axios stack, or one that can replay a real browser's ClientHello. Read your own fingerprint first, then tune the headers.
Common questions
Does changing my proxy change my TLS fingerprint?
No. A tunnelling proxy relays your handshake unchanged, so the server reads the ClientHello your own TLS library produced and only the source IP differs. Two clients behind one proxy still fingerprint separately. Changing the fingerprint means changing the TLS stack, not the network path.
How do I check my TLS fingerprint?
Connect to a public endpoint that parses the incoming ClientHello and echoes it back as JSON with the computed JA3 and JA4 values. Run the same request from your script and from a real browser on the same machine, then compare the two outputs field by field. The differences are what a detection system reads.
Does the User-Agent affect the TLS fingerprint?
No. The User-Agent is an HTTP header sent inside the encrypted tunnel after the handshake completes, while the fingerprint comes from the handshake itself. Setting a browser User-Agent on a Python client creates the mismatch detectors look for instead of hiding anything.
Related terms
Real 4G/5G mobile and residential IPs
PROXIES.SX runs carrier IPs in 100+ countries with HTTP and SOCKS5 on every endpoint. $4/GB down to $2.40/GB at volume, free endpoints and rotation, and your GB never expire.