Knowledge baseAdvanced
Export, import, backup and restore
Move a network to your own headscale and back, keep backups, bring a network back to an earlier state.
On this page
What you can do
A private network in mesh-net is a regular headscale network, and it isn't locked in:
- Export — the whole network in one archive;
- move it to your own headscale and keep the devices' addresses, names and keys;
- import a network from your headscale (or from an export) into mesh-net;
- restore a network from its backup at the same address.
Two guides do the same with one ready-made line on your server and a few simple questions: Move your headscale network to mesh-net and Run your network on your own server. This article is the reference for those who know headscale.
Export
- On the network page, open the Backup tab: Export / backup.
- Press Download the archive and confirm. The file is named like
mesh-net-office-2026-10-05.tar.gz.
A network stopped after its paid period ended can be exported too, until it is deleted — see When a network's paid period ends.
Inside: the network's headscale database — the devices with their addresses, names and keys, the routes, the users
and the access policy; the server's own key; the settings that must stay the same — the address ranges and the ending
of the full device names (dns: base_domain); and a README in English and Russian with what to set up on
your server and the command for each device. mesh-net's own API and join keys are removed from it.
The archive holds the keys of the network's devices and of its server: whoever has it can pretend to be your network. Every export is recorded in the network's notifications and emailed to the owner.
Move to your own headscale
- Set up headscale 0.28 or newer with:
server_url: https://YOUR-HOST— HTTPS on port 443;prefixesexactly100.64.0.0/10andfd7a:115c:a1e0::/48, so the devices keep their addresses;policy: mode: database— the access policy is in the database;dns: base_domainas inconfig-extract.yaml, so the full MagicDNS names stay the same (another value changes them, short names stay).YOUR-HOSTmust not be that name or lie under it: headscale doesn't start like that.
- Stop headscale, delete
db.sqlite,db.sqlite-walanddb.sqlite-shmin its data directory, putdb.sqlitefrom the archive there (owned by headscale's user) and start it. - Create your own API key and join keys:
headscale apikeys create,headscale preauthkeys create --user <user id>. - On every device, as root or administrator, add every flag the device was brought up with:
No new login is needed: the device keeps its ID, address, name, key and routes. A plaintailscale down tailscale up --login-server=https://YOUR-HOST --accept-routestailscale up --login-server=…on a running device is refused — runtailscale downfirst. - Move gateways (subnet routers, exit nodes) in the same go as the devices that use them.
- When everything has moved, delete the network in mesh-net: otherwise the devices left there keep a second copy of the network.
The README in the archive has the same steps with your network's values filled in.
Import a network
Bring a network from your own headscale — or one you exported earlier — into mesh-net. Just like creating one, it needs a paid private network that isn't created yet and a free reserved name for the new network's address: an import is never free. Without a paid network the form shows the price and the payment buttons first, and you choose the file after the payment (see A private network).
- On My networks press Import at the top right: the form Import a network from your headscale or from an Export archive opens.
- Pick the Address of the new network.
- Choose the file: the
.tar.gzarchive made by Export or by the packing script of Move your headscale network to mesh-net, ordb.sqliteof your headscale. There's no field for a separateconfig.yaml: the config is read from the archive. - Press Import in the form. The file is checked first; a bad one is refused and nothing is created. Then the network is created, and its page opens on the move card.
The new network gets the devices with their addresses, names, keys and routes, the users and the access policy. If the policy allows everything, the network gets the visual access rules with the rule “all devices → everything”; any other policy stays as custom HuJSON.
An archive brings your server's identity too, so the move is gentler. Its noise_private.key — the key
the devices know the server by — becomes the new network's key, and dns.base_domain with
dns.magic_dns of its config replace the network's own, so the full device names stay as they were, like
nas.tailnet.example.com; the other DNS settings your server gives the devices — name servers, split DNS,
search domains, extra records — come along too. A bare db.sqlite brings only the devices: the network keeps
its own key, and the full names end with its own name. Either way the devices move with the command of the
move card — or, if they reach your server by a name in a domain of your own, without any
command: Move without touching the devices.
What the import accepts
- A database of headscale 0.23 to 0.28. Older ones have no schema version — update headscale, start it once and copy the database again; newer ones can't be loaded yet.
- Device addresses inside
100.64.0.0/10andfd7a:115c:a1e0::/48— the ranges of every mesh-net network — and not reserved by Tailscale. - If the config in the archive sets
dns.base_domain: a domain name, and the address of the new network is neither that name nor under it (headscale doesn't start like that). Its other DNS settings must be readable, anddns.override_local_dnscan't be on without name servers indns.nameservers.global(headscale 0.28 doesn't start like that either).dns.extra_records_path— a file on your server — doesn't come along. If the archive holdsnoise_private.key, it must be a headscale key. - Up to 64 MB.
- A consistent copy: stop headscale before copying
db.sqlite, or copy it while it runs with:
An archive withsqlite3 /var/lib/headscale/db.sqlite ".backup /tmp/db.sqlite"db.sqlite-walinside is refused: the copy may lack the latest changes.
Two more things the result message may mention: if the database had no access policy (your headscale kept it in a file), every device reaches every other — set the rules again; devices that logged in through single sign-on (OIDC) work until their key expires, then add them with a join key.
Move the devices
After an import, the network page shows Move your devices here with the commands, and lists the devices with their status — Online here now: N of M devices. counts the ones that have already moved. Run on every device — Linux and macOS:
sudo tailscale down && sudo tailscale up --login-server=https://office.mesh-net.space
Windows, in PowerShell as administrator:
tailscale down; tailscale up --login-server=https://office.mesh-net.space
- Use the network's own address — the card shows it;
https://office.mesh-net.spaceabove is an example. - Add every flag the device was brought up with (
--advertise-routes,--accept-routes,--advertise-exit-node,--hostname…):tailscale updoesn't keep the ones you leave out. No new login is needed. - Move gateways together with the devices that use them: until a gateway moves, its routes are unreachable for the devices that already moved.
- When every device is here, turn the old server off: the devices left there keep a second copy of the network.
- The Tailscale apps for phones and desktops weren't tested with this move: if switching the server in the app asks you to log in, add the device with a join key (Add device).
Hide removes the card when you're done.
Backups
The export archive is also the network's backup. Download it before big changes — new access rules, removing devices, experiments with routes — and keep a few recent ones: the dashboard restores a network only from a file you upload.
mesh-net keeps snapshots of every network on its side too, so that a network can be brought back on another server if its server fails (more). Those are for moving networks between our servers: to roll your network back to an earlier state, use your own archives.
Restore from a backup
Restore from a backup brings the network back to the state of an export archive (or of a
db.sqlite) at the same address, so the devices from the backup reconnect by themselves. A network stopped
after its paid period ended can't be restored: renew it first.
- On the network page, under Export / backup, choose the file in Backup: archive (.tar.gz) or db.sqlite.
- Tick the box that you understand what is lost and press Restore, then confirm.
Devices added and routes approved after the backup disappear, and a custom HuJSON policy returns to its text from the backup; visual access rules are applied again from the dashboard. The network's control pauses for a few seconds. The current state is saved first; if anything fails, the network is put back automatically.
After a restore
- The devices that are in the backup reconnect by themselves within a minute; the page shows Restored from the backup and who is online already.
- Devices added after the backup aren't in it. Create a join key with Add device and run on each of
them, putting the key in place of
KEY:
The device joins as a new one, with a new key; its address may change.sudo tailscale up --login-server=https://office.mesh-net.space --force-reauth --auth-key=KEY - Visual access rules are applied again from the dashboard; a custom HuJSON policy comes back from the backup. Published services rejoin the network by themselves.
- The restore is recorded in the network's notifications and emailed to the owner.
If mesh-net moves your network to another server
mesh-net runs networks on several servers and sometimes moves a network from one to another — to free a server for maintenance, or because a server failed. You get a notification that the network moved to another mesh-net server. You don't need to do anything. The network keeps its address and second addresses, its server key, its devices with their addresses and names, join keys, access rules, sites and DNS settings — the new server is the same network, so the devices reconnect to it by themselves within seconds, with no commands. Connections between devices don't drop while they do.
- If the network's address is a name whose DNS is at another provider, leave its CNAME as it is: it points to the network's name in mesh-net's zones, and that name moves with the network.
- Published HTTP/S services keep their names. TCP/UDP publications get the public address of the new server (the ports stay the same) — the notification names it, and the network page shows it.
- If a server doesn't answer for 5 minutes, its networks come up on another server by themselves, from mesh-net's latest snapshot. A device added in the last minutes before the failure may have to join again — the notification says the time of the snapshot.
Snapshots: every 5 minutes mesh-net takes a snapshot of every network — its database, server key and settings — and keeps the latest ones on a server of its own. That is what lets a network come back on another server without the devices noticing. They don't replace your own backups.
What isn't in the archive
- mesh-net's settings of the network: published services and notification settings.
- The visual rules, groups and sites as the dashboard keeps them — the archive carries the policy built from them and the devices' routes, not the rules themselves.
- mesh-net's API and join keys.