NetNut's network was disrupted on 2026-07-02. What to inventory before you lose access, what breaks silently on the new provider, and a 48-hour cutover.
· 17 min read · Migration
Your jobs started hanging on 2026-07-02. The endpoint stopped resolving, the retry logic did what retry logic does, and the queue backed up behind it. Picking a NetNut alternative is the easy half of what happens next. The hard half is that a proxy network is not a URL. It is a session model, a username grammar, a geo taxonomy, a concurrency ceiling and a billing unit — and every one of those differs between providers. Get one wrong and traffic still flows. It flows from the wrong place, at the wrong cost, and nothing errors.
This page is the migration in order: what to extract from the old setup while you can still reach it, what maps cleanly, what breaks quietly, and how to cut over in 48 hours with a rollback still on the table.
On 2026-07-02 the FBI and Google's Threat Intelligence Group disrupted NetNut's residential proxy network, tracked as the "Popa" botnet (Krebs on Security). The network co-opted more than 2 million consumer devices globally (BleepingComputer). The operation ran with Lumen Technologies, the Shadowserver Foundation and IRS Criminal Investigation. In a single week in June 2026, Google counted 316 distinct threat clusters using NetNut exit nodes, and the action built on the January 2026 disruption of the IPIDEA proxy network (Infosecurity Magazine). The FBI said it worked with industry partners to seize hundreds of domains associated with the network, and netnut.com was replaced with a seizure notice (Krebs on Security).
That is the entire set of facts this article rests on. Culpability, the state of any proceeding, what happens to accounts, and what becomes of data held by the network are not settled enough to plan around, and we are not going to speculate about them here. Plan around the one thing that is settled: the endpoint is gone, and it went away without a deprecation window.
The wider point for procurement is not that one network was disrupted. It is that two commercial proxy networks were disrupted inside the same six months. Exit-path provenance is now an operational risk with an outage attached to it, rather than a footnote in a vendor questionnaire.
An endpoint that has been taken down does not behave like an endpoint that is returning errors. This is why the outage was worse than a bad-gateway hour.
DNS is the first thing to move, and it does not fail cleanly. A hostname
that no longer points anywhere useful either fails to resolve or resolves to
something that accepts a TCP connection and never speaks the proxy protocol.
The second case is worse. Your client sits in connect or in the CONNECT
handshake until a timeout fires — and if you never set one, that timeout is
whatever your OS default is, which is measured in minutes.
Retries amplify the outage instead of absorbing it. Exponential backoff
assumes failures are fast and transient. When each attempt costs 60 seconds of
hang instead of 200 milliseconds of 407, three retries turn one dead request
into three minutes of a held worker. A pool of 50 workers stops being a pool.
Thread accounting goes wrong before request accounting does. Held sockets occupy concurrency slots. Monitoring that alerts on error rate sees nothing, because there are no errors yet — there are no responses either.
Three changes make the next provider outage survivable, and they are worth making before you migrate rather than after:
Six things need to come out of the old configuration, and most of them are only extractable while you still have access to it. If you still have a working dashboard or a working config repository, do this first and do it today.
The list is always longer than the one in your head. Search for the hostname
string, not for the word "proxy", across: application code, .env files,
Kubernetes secrets and ConfigMaps, CI/CD variables, container images that
baked a value at build time, cron and systemd units, Terraform, browser
automation launch flags, and any Postman or curl scripts an engineer keeps
locally. Grep for the port numbers too — sticky ports are often hardcoded as
integers in a range loop, with the hostname assembled separately.
Not the one in the runbook. Rotating per request, rotating on a timer, or sticky for a bound window — and if sticky, the window length and how the session is addressed. Two systems that both say "sticky" can mean entirely different things, which is the subject of the mapping section below. If you are re-deciding rather than porting, start from matching your session model instead of from what you had.
Country, state, city, ZIP and ASN selections almost always ride inside the proxy username as delimited key-value pairs. Record the full username string verbatim for every distinct job, including delimiters and casing. Do not record your interpretation of it. Record the string.
Username and password, or IP whitelist, or both. If it is a whitelist, you need the list of source addresses you registered — NAT gateways, egress IPs, office ranges, CI runner pools. That list is not reconstructable from your code. If it is username and password, enumerate every store holding a copy: secrets manager, CI, developer laptops, that one Lambda environment variable.
The number of simultaneous connections your workers open at peak, not the
number in the plan description. Measure it: count established sockets to the
gateway at peak for an hour — concurrency and your thread
limit covers how to turn that count
into a plan size. This number decides which plan you buy and it is
the most common cause of a migration that "works in staging". Concurrency
limits surface as their own error class — on AnonEdge that is
407 THREADS_EXHAUSTED, and hitting it
looks exactly like an auth failure to a client that only logs status codes.
This is the step everyone skips and the one that decides whether the migration gets judged fairly. Without a baseline, every failure on the new provider is attributed to the new provider, including the failures you were already absorbing. Run a fixed sample — 1,000 requests against your real target list, same time of day — and record: HTTP success rate, median and p95 latency, bytes per successful response, and the geo distribution of exit addresses as your target sees them. Store the raw results, not a summary.
If you no longer have access to the old network, you cannot build this baseline. Build it on the new provider in week one anyway, so that the next migration has one.
Every dimension below has to be re-decided, not copied. The failure mode column is the reason this is a table and not a checklist — most of these do not raise an exception.
| Dimension | What to record from the old setup | How it works on AnonEdge | How it fails if you get it wrong |
|---|---|---|---|
| Endpoint | Hostname and port per job | gw.anonedge.com — one host, three port classes |
Connection hangs or refuses; loud, easy |
| Rotation | Per request, or timed | Rotating on 823 (HTTP/HTTPS) and 824 (SOCKS5) |
Silent: you get an IP, just not a fresh one |
| Sticky | Window length and how a session is addressed | A port in 10000-20000; each port is one session slot |
Silent: cookie-backed flows break at step 2 |
| Targeting | The verbatim username string | Country and ASN in the base price; state, city, ZIP and ASN filters billed at 2× | Silent: traffic exits from the wrong country |
| Auth | Credential pair or whitelisted source IPs | Username and password on the gateway | Loud: 407 on every request |
| Concurrency | Established sockets at peak | Per-plan thread limit | 407 THREADS_EXHAUSTED under load only |
| Protocol | HTTP, HTTPS or SOCKS5 | HTTP/HTTPS on 823, SOCKS5 on 824 |
Handshake failure, or a DNS leak on SOCKS5 |
| Billing unit | Per IP, per port, or per GB | Per GB, credits with no expiry | Silent: your bill moves without your code changing |
This is the single biggest silent breakage in a proxy migration. Provider A encodes a country as one token; provider B expects a different token, a different delimiter, or a different position in the string. When provider B sees a parameter it does not recognize, the common behavior is to ignore it and serve you a default exit — not to reject the request. You get 200s. You get data. The data is from the wrong country and your job has no idea.
Guard against it with an assertion, not a review. Before the first real run, send one request per configured geo to an IP-echo endpoint and assert the returned country matches what you asked for. Keep that assertion in the job as a startup check, not as a one-off test. On AnonEdge, the parameter grammar and the filter tiers are documented on the targeting reference — read it against your recorded strings rather than pattern-matching from the old syntax.
Two incompatible designs, and code written for one does not work on the other.
In a session-ID model, you generate a token, embed it in the username, and the gateway binds that token to an exit for a window. Concurrency is unbounded by the model; you can hold 10,000 distinct session tokens if your plan allows the threads.
In a port-range model — which is what AnonEdge uses — the session identifier is the port. Connect to port 10000 and you get one exit; connect to 10001 and you get another. Two workers on the same port share an exit, which is a feature if you meant it and a bug if you did not. Your session allocator becomes a port allocator, and the range size is the ceiling on concurrent distinct sessions. The port access reference lists the range and the ports open by default.
Porting between the two is a rewrite of your session-checkout function, not a find-and-replace on a connection string. Budget for it.
"Rotating" means per-request on some networks and per-interval on others. If your old setup rotated on a timer and you move to per-request rotation, any multi-step flow that used to survive by accident will start failing — the address changes between the form GET and the form POST. If you move the other way, your rate-limit profile per address goes up and targets that were tolerant become hostile. Decide explicitly which flows need continuity and route them to sticky ports; leave the rest on the rotating ports. The gateway reference covers which port class does which.
ISO 3166-1 alpha-2 is common but not universal, subdivision codes are worse, and city names are the worst of all — spelling, diacritics and which metropolitan definition is in use. Do not assume your geo list transfers. Validate every code in your list against the new provider before the cutover, and treat an empty result as a failure rather than as "no availability".
The loud failures — a 407, a refused connection, a TLS error — are cheap.
You find them in ten minutes. These are the ones that cost a quarter.
Geo drift. Country-level targeting can be satisfied by very different address populations. Same country, different ASN mix, different city distribution. If your target personalizes by region, your data changes shape without a single error.
IP reputation against your specific targets. Reputation is not a property of a pool, it is a property of a pool and a target. A network that performs well against one class of site can perform badly against yours, and the only way to know is to test against your own target list rather than against a generic benchmark page.
A different response-size profile. Different exits can get different variants of the same page: different ad payloads, different consent walls, different image sets, different amounts of client-side hydration. On per-GB billing, that moves your bill without changing a line of your code. Measure bytes per successful response during the parallel run, not just success rate.
DNS resolution location. If you move a job onto SOCKS5, whether hostnames resolve locally or at the exit decides whether your DNS queries reveal your targets to your local resolver — and it can also change which CDN edge your request lands on, which changes the content you get back.
Retry cost. Failed requests are not always free in bytes. A request that gets a 40 KB block page consumed 40 KB. Under a per-GB model that is billable traffic, and a migration that raises your failure rate raises your bill twice: once for the retries and once for the failures themselves. Budget for it before the parallel run, not after — what failures cost during a parallel run sets out which failure classes carry bytes and which do not.
The point of this plan is that the switch is gated on a number you chose in advance, and that rollback stays available for a week after you stop thinking about it.
Hours 0-4 — set the gate. Write down the pass threshold before you see any data: minimum success rate, maximum p95 latency, minimum geo-match rate, and maximum bytes per successful response, each expressed against the baseline you captured during inventory. A threshold chosen after the fact is not a threshold.
Hours 4-8 — provision and smoke test. Credentials, one rotating port, one sticky port, one geo. Assert the exit country. Assert that two requests on a rotating port return different addresses and that two requests on the same sticky port return the same one. Ten requests total. Do not proceed if any assertion fails.
Hours 8-24 — parallel run on a sample. Take 5-10% of your real workload and run it against both providers, or against the new provider and your stored baseline. Same targets, same time windows, same concurrency per worker. Capture the same four metrics. Do not tune anything during this window; you are measuring, not optimizing.
Hours 24-32 — read the numbers, then fix the obvious. Most first-run gaps are configuration, not network: a wrong geo token, a session model mismatch, a concurrency setting copied from the old plan. Fix, then re-run the sample. Two failed samples in a row means the plan or the pool type is wrong, not the config.
Hours 32-40 — ramp. 25%, then 50%, then 100%, with at least an hour at each step and the gate re-evaluated at each step. Watch requests-in-flight, not just error rate.
Hours 40-48 — cut and keep the door open. Switch fully. Leave the old configuration path in the code behind a flag, and leave the alerting on both.
Days 3-7 — hold the rollback. Do not delete the old credentials, the old whitelist entries or the old code path for a week. Migrations fail on day four, when a job that only runs weekly executes for the first time against the new setup.
Do this on pay-as-you-go rather than on an annual commitment. Traffic that does not expire means an evaluation that goes badly costs you the bytes you spent and nothing else. AnonEdge also publishes a 7-day money-back guarantee on its plans, which is the correct window for a 48-hour cutover with three days of observation after it.
The nine pages currently ranking for this topic are lists of vendors. A list of vendors is not a method. The method is a set of questions you send to every provider on your shortlist, including the one you are reading right now, and a decision rule about what a non-answer means. Twelve of those questions, with what a specific answer contains and what an evasion sounds like, are in choosing without repeating the mistake.
Two of them matter more than the rest, and they are the two most often skipped:
Send those questions to [email protected] and read our answer with the same
skepticism you would apply to anyone else's. A provider that treats the
question as adversarial has told you something useful.
Per-IP and per-GB are not convertible. A per-IP or per-port plan is a fixed cost with unbounded traffic; per-GB is a variable cost with unbounded addresses. Moving between them changes which of your engineering decisions have a price attached, and the two models are compared directly in per-IP versus per-GB after the move. What a per-GB invoice is actually counting — headers, TLS, retries and all — is re-baselining cost.
Under per-GB, the cost drivers are bytes, so the levers are: block images,
fonts, media and third-party beacons in any browser-based job; send
Accept-Encoding and actually accept the compressed response; use conditional
requests where the target honors them; stop fetching pages you already have;
and, above all, stop paying for failures — a retry storm against a target that
is blocking you is pure billable waste.
The arithmetic you need is your own, and it is two numbers: measured bytes per successful request, and requests per month. Multiply, convert to GB, multiply by the rate for the pool you need. AnonEdge lists datacenter at $0.99/GB, residential at $1.99/GB and mobile at $3.99/GB as of 2026-08-06 — check the current per-GB rates rather than trusting a figure in an article, including this one. Note that advanced target filters (state, city, ZIP, ASN) bill at 2× the standard rate, so a geo-precise job costs more per byte than a country-level one.
Do not estimate bytes from a competitor's blog post. Measure your own during the parallel run. Response sizes vary by an order of magnitude between a JSON API and a hydrated single-page app, and nobody else's number is yours.
The transport layer usually ports without changes — HTTP, HTTPS and SOCKS5 clients care about a host, a port and a credential. What does not port is everything encoded above that: username-embedded targeting parameters, how a sticky session is addressed, rotation semantics, and your concurrency assumptions. Budget a rewrite of your session-checkout logic if you are moving between a session-ID model and a port-range model.
Six things: every endpoint hostname and port across code, secrets and CI; the session model and window; the verbatim targeting username strings; the auth model plus every whitelisted source IP; peak concurrent connections measured rather than assumed; and a success-rate baseline from a fixed sample of your real targets. The last one is the one people skip, and without it you cannot tell whether the new provider is worse or just different.
Because a hostname that stops pointing at a working proxy does not necessarily refuse connections — it can accept the TCP connection and never complete the proxy handshake. Your client then waits for whatever timeout it has, which is often an OS default measured in minutes. Set explicit connect and total-request deadlines, cap retries, and alert on requests-in-flight so a hang is visible before the queue backs up.
Long enough to cover one full cycle of your traffic pattern, which for most scraping and verification workloads means at least 24 hours across a weekday-to-weekend or a business-hours-to-overnight boundary. Run 5-10% of real volume against real targets, compare against the baseline on success rate, p95 latency, geo match and bytes per response, and gate the switch on thresholds you wrote down before you saw any data.
It depends entirely on your bytes per request, which is why you measure it. Per-IP is a fixed cost with unbounded traffic and a fixed address count; per-GB is a variable cost with no address ceiling. Byte-light, address-hungry work — verification, availability checks, rank tracking — is usually cheaper per-GB. Byte-heavy work on a small address set is usually cheaper per-IP.
You need a second provider running against your real targets before you can
say anything true about either one.
Start routing on a pay-as-you-go account, point
5% of your workload at gw.anonedge.com:823, and compare the four numbers
against your baseline. If you want the shortlist questions answered in writing
first, talk to sales.