Shortest commands
--binary-tag T already in the binstore. The acquirer reuses the cached binary instead of re-acquiring it, so the operation collapses to a local symlink swap + restart per node.
Options
| Flag | Default | Effect |
|---|---|---|
--binary-tag <T> | resolved from GitHub | Pin the mx-chain-go tag. |
--config-tag <T> | leave untouched | Pin the mx-chain-mainnet-config tag. |
--proxy-tag <T> | leave untouched | Pin the proxy tag (only when a proxy is installed). |
--strategy rolling|parallel | rolling | Per-node ordering. |
--max-parallel N | 1 | Cap when --strategy parallel. |
--select '<expr>' | --all | Selector grammar. See lifecycle. |
--node N | all | Limit to specific nodes (repeatable). |
--shard <S> | all | Limit to one shard. |
--skip-validators | off | Skip validator-role nodes. |
--dry-run | off | Print the resolved plan without doing anything. |
Examples
Per-node steps
Each node goes through five idempotent steps:| Step | What |
|---|---|
Resolving | Acquire the binary into the binstore (skipped if cached) |
Stopped | systemctl stop |
ConfigApplied | Re-stamp prefs.toml for squad / observer edits |
BinaryReplaced | Atomic symlink swap of <workdir>/node to the new tag |
Started | systemctl start |
NonceVerified | Poll the local REST API until nonce is within 5 of siblings or is-syncing == 0 |
Downgrade
upgrade --binary-tag <older> reuses the binstore if the tag is cached, making the operation a local symlink swap + restart per node. If the tag isn’t cached, mxnode re-acquires it.
Pruning policy is controlled by [install].binary_keep in config.toml; the default of 3 keeps the last three tags.
Self-healing inflight.toml
Every upgrade writes a~/.local/state/mxnode/inflight.toml lock at the start, updates current_step as the orchestrator advances, and removes it on completion. The file records:
op,started_at,strategy,selectednodescompletednodes,currentnode,current_steptarget_binary_tag,target_config_tag,target_proxy_tag[identity]— owner pid + start token
cat inflight.toml after a death tells you what step the upgrade died on).
When mxnode upgrade starts and finds an existing inflight.toml, it classifies the recorded pid:
| Pid status | mxnode behaviour |
|---|---|
| Live | Refuse — another mxnode is genuinely running. |
| Dead | Clear the file, log → clearing stale inflight.toml from previous run …, proceed. |
| Indeterminate | Same as dead. |
mxnode upgrade command is the recovery procedure. Every per-node step is idempotent, so steps that already ran become no-ops the second time.
Audit log
Every upgrade attempt appends aMigrationEntry to state.toml’s migrations.entries[]:

