All posts

October 25, 20264 min readproxiesbrowserengineering

Your Proxy Provider Replaced the IP. Your Config Still Has the Old One.

A static residential IP was replaced overnight, the old address answered 407, and every login pinned to it failed. What we changed so it cannot recur.

By Scrappy Team

Static residential IPs are rented one address at a time, and that is the point: a saved login keeps working when it is replayed from the same address it signed in from. So we pin each saved login to one exit and use that exit every time.

One night our proxy provider replaced three of those addresses. The plan had automatic replacement of "invalid" proxies turned on, which is a sensible default for the provider. Our configuration — a list of host:port entries — kept the three old addresses for three days.

What a replaced address looks like

Not like a dead one. A replaced address still accepts TCP connections, because it is somebody else's proxy now. What it refuses is your credentials: every tunnel request through it was answered 407 Proxy Authentication Required.

The three were among the addresses we preferred, so they carried most of the pinned logins. Every session on one of those logins started normally and then failed on its first navigation. Over two and a half days that was about a hundred sessions, each charged and each useless.

Why nothing healed itself

We had two safety mechanisms, and they cancelled each other out.

  • An exit that failed three times was retired for two hours, so other sessions stopped using it.
  • A login whose pinned exit failed three times within thirty minutes had its pin cleared, so it could move.

The second needed three failures from the same login inside half an hour. The first guaranteed each login could fail at most once every two hours. So the pins never cleared, and the same logins failed on every scheduled run.

What we changed

A 407 is a credential refusal, not a network flap. It now sidelines the exit for six hours on the first answer, shared across every machine, and logs one error that says so.

We do not unpin on a 407. This was the tempting fix and it is wrong. A 407 is as often the whole account — a lapsed plan, a rotated password — as one replaced address, and moving forty logins off the addresses they signed in from because of a temporary account problem would do lasting damage. Those sessions fall back to another exit while the pinned one is sidelined, and try it again afterwards.

We ask the pinned exit for a tunnel before building the session. A single CONNECT through the proxy takes about 140 milliseconds, against a ten-second session start. If it is refused, the exit is sidelined and the session is built elsewhere — so a dead pin costs one probe, not a charged session that cannot load a page. If the probe cannot answer at all, we go ahead as before rather than refuse on no evidence.

A pin moves only when its address has left the pool. When a login's pinned address is no longer in our configured list at all, the session is built on the login's fallback exit and that exit becomes the new pin, once. An address that merely refused just now keeps its pins, because it may come back.

We compare our list with the provider's, every day. A daily job lists the plan's addresses through the provider's API, diffs them against our configuration in both directions, probes every configured exit with the same CONNECT the sessions use, and sends one alert if anything differs. It changes nothing itself: updating the list is a person's job, and the alert says exactly what to update.

What generalises

If you pin identities to static IPs, assume the addresses can change underneath you without notice, and plan for three things:

  1. Read the status code. A 407 through a proxy that used to work means the address or the credentials changed, not that the network is having a bad minute.
  2. Probe before you spend. A tunnel check before a session starts is cheap. A session that cannot load its first page is not.
  3. Reconcile with the source of truth. Your configuration is a copy of the provider's. Diff the copy against the original on a schedule, not after a customer notices.

This is part of why Scrappy's saved logins each keep their own exit, and why the exit is checked before a session is built on it.

Keep reading