Repository navigation
Hot Restart
Every proxy slot authenticates with the platform once and receives a client_id. Hot restart keeps that signed client JWT on disk and reuses it across restarts, so the provider comes back as the same client instead of a brand new one.
This page covers what is stored, how the toggle resolves, how to read the current state, how to turn reuse off or on, and what makes the platform hand out a new identity anyway.
- The
client_idis what the platform tracks a connection under. A new id on every restart means a new client row each time, no history, and an auth burst at startup when a box walks a large proxy list. - Reuse keeps the identity, and the reliability and location data attached to it, stable across restarts and updates.
- A restart with reuse in place does not call
/network/auth-clientat all while the stored token is still valid.
client_id and device_id are minted by the platform, not by the provider. The provider never generates, copies, or transfers an id. It keeps the token the platform issued and presents it again, and when that token has expired it asks the platform to re-sign the same client row by sending the existing ClientId to /network/auth-client. The server updates the existing network_client and device rows and returns a JWT carrying the same client_id and device_id.
Reuse is on by default since v3.23.0-fix.26. The setting resolves in this order:
- Provider control state key
hot_restart, when set (onoroff). - Environment variable
URNETWORK_HOT_RESTART, where any value other than0means on. - Default: on.
An unknown stored value falls back to on rather than silently disabling reuse after a bad write.
# The effective override, and whether it is set at all
urnet-tools set hot-restart
# hot_restart: not set for urnetwork.service (using startup default)
# The ids the provider currently holds, read from the store on disk
urnet-tools proxy ids
# PROXY CLIENT_ID NETWORK_ID AGE
# (direct) 4f2c8d1a9b7e3c5061d2e8f4a7b9c013 9a1b3c7e… 6h12m
# 10.0.0.4:8080 91bd0e5f2a6c48d73b19e0a4c8f72d55 9a1b3c7e… 6h12mproxy ids reads .client_jwts.json directly, so it works while the provider is stopped. Bearer tokens are never printed, only the assigned ids.
Startup and per-slot logs state what happened:
🔥 [hot-restart] loaded 12 stored identities (0 pruned as stale >30d); carrying forward 12
♻️ client_id: 4f2c... (reused)
✨ client_id: 91bd... (new)
The hot-restart command is a set key, not a standalone subcommand. urnet-tools hot-restart on fails with unknown command "hot-restart".
# Reuse off: the next start mints fresh identities
urnet-tools set hot-restart off
# Reuse on again (explicit on is equivalent to the default)
urnet-tools set hot-restart onoff is stored as a value for this key, it does not clear the override. There is no separate reset to the startup default: turn reuse on explicitly instead.
The override applies to the next time a slot authenticates. Proxies that are already connected keep their identity until they reconnect. If the provider is stopped, the change is queued and applied on the next start.
The environment equivalent, for a systemd user unit:
systemctl --user edit urnetwork.service[Service]
Environment=URNETWORK_HOT_RESTART=0Pass the variable at container creation. There is no default value inside the image, so leaving it unset keeps reuse on:
docker run -e URNETWORK_HOT_RESTART=0 ...# Check what a running container sees
docker exec urfix sh -c 'echo ${URNETWORK_HOT_RESTART:-1}'$HOME/.urnetwork/.client_jwts.json, or $URNETWORK_STATE_DIR/.client_jwts.json when that override is set. One entry per identity slot:
| Field | Meaning |
|---|---|
by_client_jwt |
The signed client token the platform issued |
client_id |
The id carried in that token |
network_id |
The network that minted it, used as a credential-swap guard |
minted_at |
When the entry was written, used for the 30 day prune |
The store keeps up to 10 timestamped snapshots taken before an overwrite, so a corrupted or truncated file can be inspected. Snapshots of identical content are at most one every 5 minutes, which stops a crash loop from cycling through every backup slot. A file that fails to parse is reported and the provider starts fresh instead of refusing to run.
Entries whose minted_at is older than 30 days are pruned at load time.
| Change | Result |
|---|---|
| Provider restart, same state dir, same proxy target | Same client_id (reused) |
| Stored token expired, server row still present | Renewed with the same client_id and device_id
|
| New proxy address | New slot, new client_id
|
| Different proxy credentials on the same address | New slot on the sn fork, which keys by address and auth user; same slot on 3.23-fix and meso-miner, which key by address alone |
Different account or network (~/.urnetwork/jwt replaced) |
Fresh mint, logged as network_id mismatch
|
State dir wiped, new HOME, container recreated without its volume |
Fresh mint |
minted_at older than 30 days |
Entry pruned, fresh mint on return |
| Reuse turned off | Fresh mint on every start |
Identities are per slot, never shared. Two proxies on one box do not present one id, and one id is not meant to be copied to another host.
There is one store per provider, and no per-slot delete command. Two ways to get a new id:
# Fresh ids for exactly one restart, then reuse again
urnet-tools set hot-restart off
urnet-tools restart -y
urnet-tools set hot-restart on# Reset the whole store, then start
urnet-tools stop
mv ~/.urnetwork/.client_jwts.json ~/.urnetwork/.client_jwts.json.bak
urnet-tools startSetting URNETWORK_HOT_RESTART=0 in front of urnet-tools restart does nothing: the unit and the container start from their own environment, not from the caller's shell.
Both routes replace the stored identity for every slot that connects. Turning reuse back on afterwards reuses whatever the last start wrote, so a single restart with reuse off moves the whole provider to a new identity set.
-
Proxy audit. Parking a proxy that grades as junk requires reuse. With hot restart off the audit still runs, but it observes and logs
would-parkinstead of parking, because a relaunch would otherwise mint a new identity each time. - HotSwap. A handover runs the replacement against the same state dir, so the incoming process presents the same identities as the outgoing one. The brief overlap where both processes hold connections is documented on the HotSwap page.
-
Session save and load.
urnet-tools session savebundles.client_jwts.jsontogether with the account JWT and the proxy state, so loading that bundle on another box carries the same client ids with it. The backend keeps one resident per client, so two hosts running the same bundle displace each other rather than doubling throughput. It is a way to move a provider, not to clone one.
Ids churn on every restart. Check urnet-tools set hot-restart first, then URNETWORK_HOT_RESTART in the unit environment or the container spec. A container recreated without a persistent state volume also churns, because the store is gone each time.
🔥 [hot-restart] network_id mismatch in the log. The account JWT now carries a different network_id than the stored entry, usually after switching accounts or networks. The old entries cannot be reused and are replaced on the next auth.
client limit exceeded. The platform refused a new client because the account is at its concurrent client limit. Churn makes this more likely: every fresh mint adds a row. Reuse reduces it.
A slot comes back with a new id even though reuse is on. Either the entry aged past the 30 day prune, the token could not be renewed, or the state dir changed. The log line for the slot says which path was taken.
Store reported as corrupt. The provider logs ⚠️ [jwt-store] corrupt ... starting fresh and mints new identities. The previous bytes are kept in a snapshot beside the store for inspection.
ids() { urnet-tools proxy ids 2>/dev/null | awk '$1 != "PROXY" && NF >= 2 {print $1" "$2}' | sort; }
ids > /tmp/before.txt
urnet-tools restart -y
ids > /tmp/after.txt
diff /tmp/before.txt /tmp/after.txtAn empty diff, plus ♻️ client_id: ... (reused) lines in the startup log, means every slot kept its identity. A ✨ ... (new) line for a slot you did not change is the one worth investigating.