When a proxy shows two different IP addresses, look at their shape before anything else. If one is IPv4 and the other is IPv6, you are most likely looking at one exit that has both kinds of address, reached over IPv4 by one checker and over IPv6 by the other. That is not rotation. Rotation only shows when two answers of the same family disagree, and a leak only shows when one of them is your own.
Why a proxy shows two different IP addresses
An exit on a modern residential connection is often dual-stack: the household has one IPv4 address shared by everything in the house, and IPv6 addresses for the devices themselves. When your browser goes through a proxy, it does not pick the family. Chrome hands the hostname to an HTTP or SOCKS5 proxy and lets the proxy resolve and connect, so the exit decides, based on which addresses the checker's server publishes and what the exit's network prefers. Two checkers, two answers.
There are three cases, and they need different responses:
| What the two checks show | What it usually means | What to do |
|---|---|---|
| One IPv4, one IPv6, neither yours | one dual-stack exit | nothing; compare like with like |
| Two different IPv4 (or two IPv6) | rotation, or a sticky session that expired | check the session settings |
| One of them is your own address | a leak | find which request went around the proxy |
Paste one gateway line. Every profile mints its own exitIn Mosaic: Provider minting. One gateway line, a separate exit for every 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.
How it works: Provider minting
The check that called a sticky session a pool
We learnt the first row by getting it wrong. Mosaic's proxy check samples the exit twice on purpose: a location lookup at ip-api over plain HTTP, and a tunnel probe to Cloudflare over HTTPS. Two different addresses from those two requests is how a rotating endpoint gives itself away, so the check compares them.
On one residential exit the two requests left by different families. The answers looked like this (real addresses replaced with documentation ranges):
ip-api (HTTP) 203.0.113.44
Cloudflare (TLS) 2001:db8:7c3e:5dc4::d565
The comparison was a string inequality, and 203.0.113.44 is not 2001:db8:…. It called the proxy a rotating pool three checks in a row, while both addresses stayed identical from check to check. The exit reputation report then told the operator that their sticky session was "one sample of the pool" and advised pinning the session, which they had already pinned. That was a confident wrong answer, on screen, about a proxy that was working exactly as sold.
Two families are not evidence
The fix is one rule. rotated() now returns false unless both addresses are the same family and differ. An IPv4 address and an IPv6 address cannot be compared, so they say nothing about rotation in either direction; we do not count them as proof that the exit is stable either. It is the same rule we apply to a gateway that times out once: silence is not a measurement, and neither is a comparison that could never have come out equal.
If you check by hand, do the same. Use one checker, ask it twice a minute apart, and compare the IPv4 answers with each other. Many checker pages show IPv4 and IPv6 on separate lines, which makes that easy. A sticky session that changes its IPv4 address between two such checks did rotate, and the usual reasons are in what a sticky session expiry looks like. A rotating port that ignores your session token is a separate problem, covered in why a session does not hold on a rotating port.
When the second address is yours
Most "my proxy shows two IPs" threads are about the third row, and there the cause is usually not the web request at all. With an explicit proxy, Chrome's page loads go through it. WebRTC does not have to: it sends UDP, and Chrome's SOCKS5 support carries TCP only. A leak test that shows your home address next to the proxy's has usually caught WebRTC. In Mosaic, a profile with a proxy runs with a WebRTC policy that stops UDP from going around the proxy, which is on by default.
The address a site sees decides more than the IP column. Mosaic draws a profile's timezone, language and geolocation for its proxy's measured exit, and each profile minted from a proxy provider gets its own session, so forty profiles get forty exits rather than one.




