Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12
○Not yet marked complete on this device.
Part XXV covers cross-cluster migration as a Proxmox Datacenter Manager
feature: the dialog box, the bandwidth arithmetic, and the duplicate guest the
defaults leave behind. This lesson is the layer underneath, which you need for
three reasons.
You may not run PDM. You will certainly want this in a script, because a split
is a per-guest movement schedule and nobody clicks through two hundred of them.
And when a migration fails, the error comes from this layer, not from the one
that called it.
The endpoint string, field by field
Everything distinctive about remote migration is in one parameter. Both
commands take a <target-endpoint> in this format:
apitoken — the full PVEAPIToken= header value for a token on the
target cluster. Not a password, not an SSH key. The source cluster
authenticates to the target as an ordinary API client.
host — an address of any node in the target cluster. There is no cluster
VIP concept here; you name a node. If that node is down, the migration does not
fail over to a sibling, so pick a node that is healthy at the time and consider
which one your script chooses.
fingerprint — optional, and the field most worth caring about. It pins
the target’s TLS certificate. Omit it against a cluster using the default
self-signed certificate and you are copying disks across a network with no
verification of who is receiving them.
port — optional, defaults to the API port, 8006. Present because estates
publish the API behind a different port often enough to matter.
Read-only / Safeget the target's certificate fingerprint, on the target— Read-only. Run this on the target node named in host=, and transfer the value out of band. Reading the fingerprint from the source over the same untrusted path you are trying to authenticate defeats the purpose.
The token lives on the target cluster and should not be an administrator. Build
it from the privileges the operation actually needs.
Configuration changecreate a receiving identity on the TARGET cluster— Changes access control on the target cluster. Creates a dedicated user and a privilege-separated token, then grants a purpose-built role. The token secret is printed once and never again.
TARGET_USER="migrate-in@pve"
TOKEN_ID="fromsitea"
pveum user add "$TARGET_USER" --comment "Receives remote migrations from site-a"
pveum role add MigrateReceive --privs "VM.Allocate VM.Config.Disk VM.Config.Network VM.Config.Options VM.Config.HWType VM.Config.CPU VM.Config.Memory VM.Config.Cloudinit VM.PowerMgmt VM.Audit Datastore.AllocateSpace Datastore.Audit Sys.Incoming SDN.Use"
pveum user token add "$TARGET_USER" "$TOKEN_ID" --privsep 1
Configuration changescope the token, on the TARGET cluster— Changes access control. A privilege-separated token starts with no permissions of its own; effective permissions are the intersection of the user's and the token's. Grant on the narrowest paths that work — the VM tree, the destination storage, and the node that terminates the stream.
Service impact possiblemigrate VM 141 from this cluster to a remote cluster— Copies every disk of VM 141 across the network to the target cluster and, with --online, live-migrates its memory. The source guest is left in a stopped state. Read the whole lesson, and Part XXV, before running this against anything that matters.
Service impact possiblethe container equivalent— Containers have no live migration. --restart shuts the container down, moves it, and starts it at the destination, with --timeout controlling how long the shutdown is given before it is forced.
The two mappings are mandatory and their shorthands are covered in Part XXV:
a single ID maps everything to it, and the special value 1 maps each source
name to itself. The trap is also covered there and is worth repeating in one
line: --target-bridge 1 succeeds whenever a same-named bridge exists at the
destination, regardless of what network that bridge is attached to.
What does not travel
The guest arrives. A surprising amount of what surrounded it does not, because
those things are cluster configuration rather than guest configuration.
Does not travel
Where it lived
What to do
Backup jobs
Cluster config, /etc/pve/jobs.cfg
Create a job at the destination and confirm it has run once
PBS backup history
Keyed by guest type and ID on the PBS datastore
Decide whether the old chain is retained, and for how long
Firewall rules at cluster level and security groups
Cluster config
Recreate; guest-level rules in the guest config do travel
HA resource membership, groups and rules
Cluster config
Re-add at the destination if the guest needs HA
Pool membership
Cluster config
Re-add, and re-check the ACLs that depended on it
Replication jobs (pvesr)
Cluster config
Recreate against a destination peer, or drop
ACLs granting users access to this VMID
Cluster config
Recreate on the target cluster
Notification matchers referencing the guest
Cluster config
Recreate
Monitoring targets, CMDB entries, DNS
Outside PVE entirely
Update; nothing will tell you
Storage-level snapshots on the source volumes
On the source storage
See below
That last row deserves its own paragraph. Guest snapshots are a storage feature
and the destination storage may not support them in the same way — a guest
living on ZFS with a snapshot tree, moved onto an LVM-thin or a directory-backed
store, will not arrive with an equivalent tree. Treat a snapshot history as
something you deliberately abandon or deliberately preserve elsewhere, and
decide before the move rather than discovering it after.
Remote migration or backup and restore?
Both move a guest between clusters. They are not interchangeable.
qm remote-migrate
Backup, copy, restore
Downtime
Near-zero with --online, after a long copy
Full: restore duration plus start
Total elapsed time
One disk copy
Backup, transfer, restore — often longer
Source left as
Stopped copy of the guest
Untouched and running
Rollback
Start the stopped source
Do nothing; the source never stopped
Depends on
An experimental code path, both clusters healthy and reachable
Backups you already take
Works when the source is dead
No
Yes, if the backup is off-site
Preserves VMID
With --target-vmid, if free
Yes, if free
Scriptable in bulk
Yes
Yes
The honest guidance: use remote migration when downtime is the binding
constraint and both clusters are healthy, and use backup/restore when
correctness and reversibility matter more than minutes. For a planned estate
split done over several weekends, backup/restore is frequently the better tool,
and it has the enormous advantage of exercising the restore path you claim to
have.
Key takeaways
The endpoint is apitoken=...,host=...[,fingerprint=...][,port=...]. The
fingerprint is optional and pinning it is the difference between an
authenticated transfer and a hopeful one. The port defaults to 8006.
The receiving token belongs on the target cluster, privilege-separated, and
needs Sys.Incoming — a node-level privilege granted on / or
/nodes/<node>, not on /vms. Its absence fails the migration late.
The credential appears in ps and in shell history. Source it from a file or
a secret store, and rotate it when the campaign ends.
Bridge and storage maps are mandatory; 1 maps each name to itself and is the
silent failure when a same-named bridge is on a different network.
Backup jobs, PBS history, cluster firewall rules, HA membership, pool
membership, replication jobs, ACLs and monitoring do not travel. Snapshots may
not survive a change of storage backend.
The transport is the API on 8006, not SSH on 22, and it reuses the
pvesm export/import volume machinery — which is why formats convert
implicitly.
A failed migration has no resume. Stabilise the source, read the destination
task log, remove orphaned volumes with pvesm list/pvesm free, then retry.
For a planned split, backup and restore is often the better tool: slower, but
reversible, non-experimental, and it exercises your restore path.
Knowledge check
Knowledge check · 5 questions
Q1. A receiving token on the target cluster has VM.Allocate, VM.Config.Disk and Datastore.AllocateSpace granted on /vms and on the destination storage. The first remote migration authenticates, begins, and then fails with a permission error some way in. What is missing?
Q2. A VM is remotely migrated from cluster A to cluster B and arrives working. Which of these are left behind because they are cluster configuration rather than guest configuration? Select all that apply.
Q3. A 3 TB remote migration fails at roughly 80% when the inter-site link drops. What is the correct first action?
Q4. Remote migration authenticates to the target cluster API, so the firewall opening it needs between two estates is the API port rather than SSH on port 22 — and the datacenter.cfg migration type setting does not apply to it.
Q5. An estate is splitting over several weekends and 180 guests must move. Downtime of an hour per guest is acceptable. What is the better default tool, and why?
Passing score: 75%. Answers are checked in this browser.