Migrating a Validator¶
Danger
SLASHING RISK: DOUBLE SIGNING
Never run the same validator keys on two different machines at the same time. This can result in a slashing event, causing you to be ejected from the network and lose a significant portion of your stake.
Always ensure the old validator is completely stopped and disabled before starting the new one.
Overview¶
This document explains how to safely move an Ethereum validator from one machine to another (for example, from a cloud VPS or an old desktop to an Ethereum on ARM board), while minimizing the risk of slashing.
The procedure applies to common consensus clients:
Grandine
Lighthouse
Nimbus
Prysm
Teku
Lodestar
It assumes you already have working execution and consensus clients on both machines.
Prerequisites¶
New node: Your Ethereum on ARM board (Rock 5B, Orange Pi, etc.) must be installed, powered on, and fully synced (execution + consensus).
Old node: You must have terminal access to your current validator host.
Key material: Your original
keystore-m_*.jsonfiles and their password must be safely backed up and available.
Step 1: Sync the new node (without keys)¶
Start your execution client on the new node (Geth, Nethermind, Erigon, Reth) and allow it to fully sync.
Start your consensus client (Lighthouse, Nimbus, Prysm, Teku, Lodestar, Grandine) and allow the beacon node to reach head.
Do NOT import validator keys or start any validator service yet.
The new node must be fully synced before it is allowed to sign duties.
Step 2: Stop the old validator and export slashing protection¶
Note
On Ethereum on ARM, validator services are client-specific.
Stop the validator before exporting slashing protection.
sudo systemctl stop lighthouse-validator
Export slashing protection from the old node.
lighthouse slashing-protection export \
--datadir /home/ethereum/.lighthouse \
--output slashing_protection.json
Stop the validator before exporting slashing protection.
sudo systemctl stop prysm-validator
Export slashing protection from the old node.
prysmctl slashing-protection export \
--datadir=/home/ethereum/.eth2 \
--output=slashing_protection.json
Stop the validator before exporting slashing protection.
sudo systemctl stop nimbus-validator
Export slashing protection from the old node.
nimbus_beacon_node slashingdb export \
--data-dir=/home/ethereum/.local/share/nimbus \
slashing_protection.json
Stop the validator before exporting slashing protection.
sudo systemctl stop teku-validator
Export slashing protection from the old node.
teku slashing-protection export \
--data-path=/home/ethereum/.teku \
--to=slashing_protection.json
Stop the validator before exporting slashing protection.
sudo systemctl stop lodestar-validator
Export slashing protection from the old node.
lodestar validator slashing-protection export \
--network <NETWORK> \
--file slashing_protection.json \
--dataDir /home/ethereum/.lodestar-validator
Stop the validator before exporting slashing protection.
sudo systemctl stop grandine-validator
Export slashing protection from the old node.
grandine --network <NETWORK> interchange export slashing_protection.json
Verify that
slashing_protection.jsonexists and back it up securely.
Step 3: Disable and clean up the old validator¶
Disable the validator service so it cannot auto-start:
sudo systemctl disable lighthouse-validator
sudo systemctl disable prysm-validator
sudo systemctl disable nimbus-validator
sudo systemctl disable teku-validator
sudo systemctl disable lodestar-validator
sudo systemctl disable grandine-validator
Confirm no validator processes are running:
ps aux | grep validator | grep -v grep
Once backups are confirmed, delete or move validator keys from the old machine.
Wait 2–3 epochs (≈15–20 minutes) and confirm on a beacon explorer that attestations are missing:
Ethereum: https://beaconcha.in
Gnosis: https://gnosischa.in
Step 4: Transfer keystores and slashing protection¶
Copy to the new Ethereum on ARM node:
keystore-m_*.jsonfilesslashing_protection.json
Example:
scp keystore-m_*.json ethereum@new-node:/home/ethereum/validator_keys/
scp slashing_protection.json ethereum@new-node:/home/ethereum/
Ensure ownership matches the ethereum user.
Step 5: Import keys and slashing protection (new node)¶
Note
Replace <NETWORK> with mainnet, gnosis or hoodi.
Import slashing protection before starting the validator.
Import keys:
grandine --network <NETWORK> validator import \
--data-dir /home/ethereum/.grandine-validator \
--keystore-dir /home/ethereum/validator_keys \
--keystore-password-file /home/ethereum/password.txt
Import slashing protection:
grandine --network <NETWORK> interchange import slashing_protection.json
Import keys:
lighthouse account validator import \
--network <NETWORK> \
--directory /home/ethereum/validator_keys \
--datadir /home/ethereum/.lighthouse
Import slashing protection:
lighthouse slashing-protection import \
--datadir /home/ethereum/.lighthouse \
slashing_protection.json
Import keys:
lodestar validator import \
--network <NETWORK> \
--directory /home/ethereum/validator_keys \
--dataDir /home/ethereum/.lodestar-validator
Import slashing protection:
lodestar validator slashing-protection import \
--network <NETWORK> \
--file slashing_protection.json \
--dataDir /home/ethereum/.lodestar-validator
Import keys:
nimbus_beacon_node deposits import \
--data-dir=/home/ethereum/.local/share/nimbus \
/home/ethereum/validator_keys
Import slashing protection:
nimbus_beacon_node slashingdb import \
--data-dir=/home/ethereum/.local/share/nimbus \
slashing_protection.json
Import keys:
prysmctl accounts import \
--keys-dir=/home/ethereum/validator_keys \
--wallet-dir=/home/ethereum/.eth2validators
Import slashing protection:
prysmctl slashing-protection import \
--datadir=/home/ethereum/.eth2 \
--input=slashing_protection.json
Import keys:
teku validator-client import-keystores \
--data-path=/home/ethereum/.teku \
--from=/home/ethereum/validator_keys \
--recursive=true
Import slashing protection:
teku slashing-protection import \
--data-path=/home/ethereum/.teku \
--from=slashing_protection.json
Step 6: Start the validator service¶
Enable and start only the validator you use:
sudo systemctl enable --now lighthouse-validator
Note
If you are using MEV-Boost or Commit-Boost, you should use the -mev
systemd service variants instead. For example:
lighthouse-beacon-mevinstead oflighthouse-beaconlighthouse-validator-mevinstead oflighthouse-validator
sudo systemctl enable --now prysm-validator
sudo systemctl enable --now nimbus-validator
sudo systemctl enable --now teku-validator
sudo systemctl enable --now lodestar-validator
sudo systemctl enable --now grandine-validator
Follow logs:
sudo journalctl -fu lighthouse-validator
Verify on a beacon explorer that:
Validator is
ActiveAttestations are successful
Reinstalling the OS (Re-flashing SD Card)¶
If you re-flash the SD card while using NVMe storage:
Flash the new Ethereum on ARM image.
Boot the device. The
first-bootscript will detect the existing/home/ethereumpartition and will not format it.If
ethereumonarm-config-syncwas enabled, configs will be restored.Re-enable services:
sudo systemctl enable --now geth sudo systemctl enable --now lighthouse-beacon sudo systemctl enable --now lighthouse-validator
If using MEV-Boost or Commit-Boost:
sudo systemctl enable --now mev-boost sudo systemctl enable --now commit-boost
Additional safety recommendations¶
Always keep offline backups of keystores and slashing protection JSON.
Enable doppelganger protection where supported during first startup.
Slashing protection (EIP-3076) is your primary defense — waiting alone is not sufficient.