How to Run an Ethereum Node (Step-by-Step Guide)

How to Run an Ethereum Node (Step-by-Step Guide)
Published on Aug 28, 2024 Updated on Apr 10, 2026

Setting up an Ethereum node can feel overwhelming, especially if you're unsure where to begin. Running your own Ethereum node gives you direct access to the network and full control over your data. This guide will walk you through everything you need to know to get your Ethereum node up and running.

By the end of this guide, you'll have a full Ethereum node running, with Geth as your execution client and Prysm as your consensus client. Optional steps for setting up a validator node to earn staking rewards are also included.

#Prerequisites

To follow this guide, ensure you have the following:

  • Some knowledge of Ethereum

  • Basic knowledge of the Linux command line

  • An Ubuntu 24.04 LTS server with:

    • Minimum requirements:

      • CPU with 2+ cores

      • 8 GB RAM

      • 2TB SSD

      • Internet connection speed of 10+ MB/s

    • Recommended requirements:

      • Fast CPU with 4+ cores

      • 16 GB+ memory (RAM)

      • 2+ TB fast SSD

      • Internet connection speed of 25+ MB/s

Set up your Web3 server in minutes

Optimize cost and performance with custom or pre-built dedicated bare metal servers for blockchain workloads. High uptime, instant 24/7 support, pay in crypto.

#Understanding Ethereum Nodes

Before getting into the steps involved in running an Ethereum node, you must understand what an Ethereum node is. In this section, you'll go through what an Ethereum node is and the different types.

#What is an Ethereum node?

An Ethereum node is software (or a device running this software) that downloads and maintains a copy of the Ethereum blockchain. It verifies the validity of each block, keeps its copy up to date with new blocks and transactions, and helps other nodes synchronize their copies of the blockchain.

There are three main types of Ethereum nodes:

Full nodes store the entire Ethereum blockchain, while light nodes rely on others to provide them with blockchain data.

There are different types of nodes, each serving a unique purpose:

  • Full Nodes: These nodes store the entire history of the Ethereum blockchain and check every transaction. They provide the highest level of security and decentralization.

  • Light Nodes: Light nodes store only a small part of the blockchain and rely on full nodes for the data they need, making them faster and easier to run. They are more resource-efficient and suitable for devices with limited storage.

  • Archive Nodes: These nodes are full nodes that also keep a historical archive of every state of the blockchain, allowing them to reconstruct any past state. They’re mainly used for looking up old data.

Running an Ethereum node means contributing to the security, decentralization, and overall health of the Ethereum network by ensuring that transactions are validated and that the blockchain remains consistent across all participants.

#How to run an Ethereum node

After the merge, running an Ethereum node involves two main components: an execution client and a consensus client, which need to be run together. The execution client (like Geth) processes transactions and smart contracts, while the consensus client (like Prysm) manages the proof-of-stake consensus process. The two clients communicate using a shared secret to keep the node synchronized with the Ethereum network, helping to secure and maintain the blockchain.

There are several execution and consensus clients available for running an Ethereum node, each with its own features and strengths. However, in this tutorial, we’ll be using Geth as the execution client and Prysm as the consensus client

#Step 1: Create a server

Get a server up and running either locally or from a cloud provider. A dedicated server from Cherry Servers was used here.

#Step 2: Connect to the server

Next, connect to the server via SSH. You can do this using the following format:

Command Line
ssh user@server-ip

#Step 3: Update system packages

After connecting to the server, ensure the system is up to date and secure. Run the following commands to update the system packages, upgrade any existing packages, and remove those that are no longer needed:

Command Line
apt -y update && apt -y upgrade
apt dist-upgrade && apt autoremove
OutputHit:1 http://repo.cherryservers.com/ubuntu noble InRelease Hit:2 http://repo.cherryservers.com/ubuntu noble-updates InRelease Hit:3 http://repo.cherryservers.com/ubuntu noble-backports InRelease Hit:4 http://repo.cherryservers.com/ubuntu noble-security InRelease Hit:5 http://se.archive.ubuntu.com/ubuntu noble InRelease Hit:6 http://se.archive.ubuntu.com/ubuntu noble-updates InRelease Hit:7 http://se.archive.ubuntu.com/ubuntu noble-security InRelease Hit:8 http://se.archive.ubuntu.com/ubuntu noble-backports InRelease Reading 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done

100 packages can be upgraded.

Calculating upgrade... Done

The following NEW packages will be installed:
  linux-headers-6.8.0-106
  linux-image-6.8.0-106-generic
  linux-modules-6.8.0-106-generic
  ...

The following packages will be upgraded:
  base-files, curl, openssl, python3.12, systemd, vim, ...
  
100 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
OutputReading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
  linux-headers-6.8.0-90 linux-tools-6.8.0-90
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
  linux-headers-6.8.0-90-generic linux-image-6.8.0-90-generic linux-modules-6.8.0-90-generic linux-modules-extra-6.8.0-90-generic linux-tools-6.8.0-90-generic
0 upgraded, 0 newly installed, 5 to remove and 0 not upgraded.
After this operation, 196 MB disk space will be freed.

Do you want to continue? [Y/n] Y

Removing linux-image-6.8.0-90-generic...
Removing linux-headers-6.8.0-90-generic...

Updating GRUB configuration...
Found linux image: /boot/vmlinuz-6.14.0-37-generic
done

Next, restart the system to apply any updates that require a reboot:

Command Line
reboot

After the reboot completes, reconnect to the server via SSH before continuing to the next step.

#Step 4: Create a non-root user

To reduce the risk of accidental changes, avoid using the root user. Instead, create a new user with sudo privileges.

Create a non-root user with sudo privileges and switch to the new user by running the following commands. Replace demo-user with your preferred username:

Command Line
adduser demo-user
usermod -aG sudo demo-user
su - demo-user
Outputinfo: Adding user `demo-user' ...
info: Selecting UID/GID from range 1000 to 59999 ...
info: Adding new group `demo-user' (1001) ...
info: Adding new user demo-user' (1001) with group demo-user (1001)' ...
info: Creating home directory `/home/demo-user' ...
info: Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for demo-user
Enter the new value, or press ENTER for the default
    Full Name []:
    Room Number []:
    Work Phone []:
    Home Phone []:
    Other []:
Is the information correct? [Y/n] Y
info: Adding new user demo-user' to supplemental / extra groups users' ...
info: Adding user demo-user' to group users' ...

#Step 5: Verify system time

Next, confirm the system time, timezone, and clock synchronization. Validators rely on accurate time to submit attestations at the right moment. If the clock drifts, your node misses attestations and risks penalties.

Command Line
timedatectl
               Local time: Sun 2026-03-22 17:53:28 UTC
           Universal time: Sun 2026-03-22 17:53:28 UTC
                 RTC time: Sun 2026-03-22 17:53:28
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Confirm that System clock synchronized shows yes and NTP service shows active. If System clock synchronized shows no, restart the time sync service:

Command Line
sudo systemctl restart systemd-timesyncd

Then re-run timedatectl to confirm the clock is now synchronized.

#Step 6: Configure the firewall

To ensure your Ethereum node can communicate with the network while staying secure, you need to configure the firewall to allow specific ports. Run the following commands to open the ports required by the clients:

Command Line
sudo ufw allow 30303/tcp
sudo ufw allow 30303/udp
sudo ufw allow 12000/udp
sudo ufw allow 13000/tcp
sudo ufw allow 22/tcp
  • Port 30303/TCP and 30303/UDP are used for Geth peer-to-peer connections.

  • Port 12000/UDP is used for Prysm beacon node discovery.

  • Port 13000/TCP is used for Prysm beacon node communication.

  • Port 22/TCP is for SSH access.

Then enable the firewall on your server using:

Command Line
sudo ufw enable

Type y when prompted, then press Enter, and you should get an output similar to this:

Output Firewall is active and enabled on system startup

Finally, confirm the status of your firewall:

Command Line
sudo ufw status
OutputStatus: active
To                         Action      From
--                         ------      ----
30303/tcp                  ALLOW       Anywhere
30303/udp                  ALLOW       Anywhere
12000/udp                  ALLOW       Anywhere
13000/tcp                  ALLOW       Anywhere
22/tcp                     ALLOW       Anywhere
30303/tcp (v6)             ALLOW       Anywhere (v6)
30303/udp (v6)             ALLOW       Anywhere (v6)
12000/udp (v6)             ALLOW       Anywhere (v6)
13000/tcp (v6)             ALLOW       Anywhere (v6)
22/tcp (v6)                ALLOW       Anywhere (v6)

#Step 7: Generate authentication secret

For Geth (the execution client) and Prysm (the consensus client) to communicate securely, they need a shared secret, known as a JSON Web Token (JWT). This token ensures that only authorized clients can interact with each other.

Before generating the secret, create dedicated users for each client. This minimizes the risk of one client affecting the other and isolates their files and processes.

Start by creating the users and assigning them to a common group:

Command Line
sudo adduser --home /home/geth --disabled-password --gecos 'Geth Client' geth
sudo adduser --home /home/prysm-beacon --disabled-password --gecos 'Prysm Beacon Client' prysm-beacon
sudo groupadd eth
sudo usermod -a -G eth geth
sudo usermod -a -G eth prysm-beacon
Outputinfo: Adding user geth' ... 
info: Selecting UID/GID from range 1000 to 59999 ... 
info: Adding new group geth' (1002) ... 
info: Adding new user geth' (1002) with group geth (1002)' ... 
info: Creating home directory /home/geth' ... 
info: Copying files from /etc/skel' ... 
info: Adding new user geth' to supplemental / extra groups users' ... 
info: Adding user geth' to group users' ...

Next, create a directory to store the JWT secret, set the necessary permissions, and generate the secret:

Command Line
sudo mkdir -p /var/lib/secrets
sudo chgrp -R eth /var/lib/ /var/lib/secrets
sudo chmod 750 /var/lib/ /var/lib/secrets
sudo openssl rand -hex 32 | tr -d '\n' | sudo tee /var/lib/secrets/jwt.hex > /dev/null

Then set permissions on the secret file so that only the root user and the clients' users have access to it:

Command Line
sudo chown root:eth /var/lib/secrets/jwt.hex
sudo chmod 640 /var/lib/secrets/jwt.hex

#Step 8: Create data directories

To keep each client's data organized, create dedicated directories where Geth and Prysm will store their data.

Run the following commands to create the data directories for each client:

Command Line
sudo -u geth mkdir /home/geth/geth
sudo -u prysm-beacon mkdir /home/prysm-beacon/beacon

These directories will be used by Geth and Prysm to store blockchain data, logs, and other necessary files.

#Step 9: Install and configure execution client (Geth)

In this step, you'll install Geth and configure it to run as a system service. This ensures that Geth starts automatically when you boot your server and will continue to run as long as the server is on.

Add the Ethereum PPA and Install Geth:

Start by adding the Ethereum PPA (Personal Package Archive) to your system's repositories:

Command Line
sudo add-apt-repository -y ppa:ethereum/ethereum
OutputRepository: 'Types: deb
URIs: https://ppa.launchpadcontent.net/ethereum/ethereum/ubuntu/
Suites: noble
Components: main
'
More info: https://launchpad.net/~ethereum/+archive/ubuntu/ethereum
Adding repository.
Get:1 http://repo.cherryservers.com/ubuntu noble InRelease [8,121 B]
Get:2 http://repo.cherryservers.com/ubuntu noble-updates InRelease [8,145 B]
Get:3 http://repo.cherryservers.com/ubuntu noble-backports InRelease [8,195 B]
Get:4 http://repo.cherryservers.com/ubuntu noble-security InRelease [8,148 B]
Get:5 http://repo.cherryservers.com/ubuntu noble-updates/universe amd64 Packages [1,999 kB]
Get:6 https://ppa.launchpadcontent.net/ethereum/ethereum/ubuntu noble InRelease [18.1 kB]
Get:7 https://ppa.launchpadcontent.net/ethereum/ethereum/ubuntu noble/main amd64 Packages [2,665 B]
Fetched 2,052 kB in 1s (3,832 kB/s)
Reading package lists... Done
W: Download is performed unsandboxed as root as file '/var/lib/apt/lists/partial/ppa.launchpadcontent.net_ethereum_ethereum_ubuntu_dists_noble_InRelease' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)

Note: You might see a warning about “unsandboxed downloads.” This happens when APT cannot access /var/lib/apt/lists/partial as the _apt user due to incorrect permissions. APT falls back to running downloads as root. This does not affect installation, so you can continue.

If you want to fix it, run:

Command Line
sudo chown -R _apt:root /var/lib/apt/lists
sudo chmod 700 /var/lib/apt/lists/partial

Then update the system repository and install Geth:

Command Line
sudo apt update 
sudo apt install ethereum
OutputGet:1 http://repo.cherryservers.com/ubuntu noble InRelease
Get:2 http://se.archive.ubuntu.com/ubuntu noble InRelease
Get:3 https://ppa.launchpadcontent.net/ethereum/ethereum/ubuntu noble InRelease
...

Fetched 80.5 MB in 4s (21.5 MB/s)

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done

All packages are up to date.
OutputReading package lists... Done
Building dependency tree... Done
Reading state information... Done

The following NEW packages will be installed:
  abigen, clef, evm, geth, rlpdump, ethereum

0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 51.0 MB of archives.
After this operation, 158 MB of additional disk space will be used.

Do you want to continue? [Y/n] Y

Fetched 51.0 MB in 2s (21.2 MB/s)

Unpacking packages...
Unpacking abigen (1.17.1) ...
Unpacking clef (1.17.1) ...
Unpacking evm (1.17.1) ...
Unpacking geth (1.17.1) ...
Unpacking rlpdump (1.17.1) ...
Unpacking ethereum (1.17.1) ...

Setting up packages...
Setting up geth (1.17.1) ...
Setting up ethereum (1.17.1) ...

You can confirm the installation using:

Command Line
geth version
OutputGeth
Version: 1.17.1-stable
Git Commit: 16783c167c4be5e6675fd8de0d1b762c88d6232f
Architecture: amd64
Go Version: go1.25.7
Operating System: linux
GOPATH=
GOROOT=

Create a Systemd Service for Geth:

To manage Geth as a background service, you'll create a systemd service file. This file defines how Geth should be started, stopped, and restarted.

Open the service file in a text editor:

Command Line
sudo nano /etc/systemd/system/geth.service

Add the following configuration to the file:

[Unit]

Description=Geth Full Node
After=network-online.target
Wants=network-online.target

[Service]

Type=simple
Restart=always
RestartSec=5s
User=geth
WorkingDirectory=/home/geth
ExecStart=/usr/bin/geth \
  --http \
  --http.api eth,net,engine,admin \
  --mainnet \
  --datadir /home/geth/geth \
  --authrpc.jwtsecret /var/lib/secrets/jwt.hex

[Install]
WantedBy=multi-user.target
  • --http enables the HTTP-RPC server, allowing other services to communicate with Geth.

  • --http.api eth,net,engine,admin specifies which APIs are accessible over HTTP.

  • --mainnet connects Geth to the Ethereum mainnet.

  • --datadir /home/geth/geth sets the directory where Geth stores its blockchain data.

  • --authrpc.jwtsecret /var/lib/secrets/jwt.hex authenticates communication with Prysm using the shared JWT secret.

Start and Enable the Geth Service:

After saving the service file, reload the systemd daemon to apply the changes, start the Geth service, and enable it to start on boot:

Command Line
sudo systemctl daemon-reload
sudo systemctl start geth
sudo systemctl enable geth
OutputCreated symlink /etc/systemd/system/multi-user.target.wants/geth.service → /etc/systemd/system/geth.service.

Check the Status of the Geth Service:

Verify that Geth is active and running correctly by checking its status:

Command Line
sudo systemctl status geth
Output● geth.service - Geth Full Node
     Loaded: loaded (/etc/systemd/system/geth.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-03-23 08:23:58 UTC; 23s ago
   Main PID: 5092 (geth)
      Tasks: 14 (limit: 76585)
     Memory: 57.3M (peak: 59.0M)
        CPU: 5.497s
     CGroup: /system.slice/geth.service
             └─5092 /usr/bin/geth --http --http.api eth,net,engine,admin --mainnet --datadir /home/geth/geth --authrpc.jwtsecret /var/lib/secrets/jwt.hex

Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.934] Started P2P networking                   self=enode://5c9e736bc51891bd2f49663fd5f5a58291f5a315ef47fcf98b89a6>
Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.934] IPC endpoint opened                      url=/home/geth/geth/geth.ipc
Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.934] Loaded JWT secret file                   path=/var/lib/secrets/jwt.hex crc32=0x45d63efe
Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.935] HTTP server started                      endpoint=127.0.0.1:8545 auth=false prefix= cors= vhosts=localhost
Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.935] WebSocket enabled                        url=ws://127.0.0.1:8551
Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.935] HTTP server started                      endpoint=127.0.0.1:8551 auth=true  prefix= cors=localhost vhosts=lo>
Mar 23 08:23:58 demo geth[5092]: INFO [03-23|08:23:58.935] Started log indexer
Mar 23 08:23:59 demo geth[5092]: INFO [03-23|08:23:59.766] New local node record                    seq=1,774,254,238,933 id=10ee995279ea7d0d ip=185.8.104.175 udp=3030>
Mar 23 08:24:08 demo geth[5092]: INFO [03-23|08:24:08.937] Looking for peers                        peercount=0 tried=32 static=0

You can quit with Ctrl + C. This won't affect the running service.

To view the logs, run the command:

Command Line
sudo journalctl -fu geth

When you run the command to check the logs, you may see a message: "Post-merge network, but no beacon client seen. Please launch one to follow the chain!"

OutputMar 23 08:26:41 demo geth[5092]: INFO [03-23|08:26:41.271] Looking for peers                        peercount=31 tried=44 static=0
Mar 23 08:26:51 demo geth[5092]: INFO [03-23|08:26:51.507] Looking for peers                        peercount=33 tried=46 static=0
Mar 23 08:27:01 demo geth[5092]: INFO [03-23|08:27:01.553] Looking for peers                        peercount=34 tried=57 static=0
Mar 23 08:29:33 demo geth[5092]: WARN [03-23|08:29:33.956] Post-merge network, but no beacon client seen. Please launch one to follow the chain!

You're seeing this message because the execution client requires a connected consensus client to follow the chain after the merge. This message indicates that Geth hasn't detected a running consensus client yet.

To fix this, set up and launch the Prysm client (consensus client) as described in the next steps. Once Prysm is running and connected to Geth, the message will disappear.

#Step 10: Configure consensus client (Prysm)

Now that Geth is up and running, the next step is to set up the Prysm beacon node, which acts as the consensus client.

Download and Prepare the Prysm Script:
First, create a directory for the Prysm script, download it, and make it executable:

Command Line
sudo -u prysm-beacon mkdir /home/prysm-beacon/bin
sudo -u prysm-beacon curl https://raw.githubusercontent.com/OffchainLabs/prysm/master/prysm.sh --output /home/prysm-beacon/bin/prysm.sh
sudo -u prysm-beacon chmod +x /home/prysm-beacon/bin/prysm.sh

Create a Systemd Service for Prysm:
Similar to how you configured Geth, you'll create a systemd service file for Prysm beacon client.

Open the service file in a text editor:

Command Line
sudo nano /etc/systemd/system/prysm-beacon.service

Add the following configuration to the file:

[Unit]

Description=Prysm Beacon Chain
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
Restart=always
RestartSec=5s
User=prysm-beacon
ExecStart=/home/prysm-beacon/bin/prysm.sh beacon-chain \
  --mainnet \
  --datadir /home/prysm-beacon/beacon \
  --execution-endpoint=http://127.0.0.1:8551 \
  --jwt-secret=/var/lib/secrets/jwt.hex \
  --suggested-fee-recipient=YourWalletAddress \
  --checkpoint-sync-url=https://beaconstate.info \
  --genesis-beacon-api-url=https://beaconstate.info \
  --accept-terms-of-use

[Install]
WantedBy=multi-user.target
  • --execution-endpoint=http://127.0.0.1:8551 points Prysm to the local Geth client.

  • --jwt-secret=/var/lib/secrets/jwt.hex allows Prysm to authenticate its communication with Geth using the shared JWT secret.

  • --suggested-fee-recipient=YourWalletAddress should be replaced with your Ethereum wallet address.

  • --mainnet connects Prysm to the Ethereum mainnet.

  • --datadir /home/prysm-beacon/beacon sets the directory where Prysm stores its beacon chain data.

  • --checkpoint-sync-url=https://beaconstate.info syncs the beacon node from a checkpoint instead of from genesis, which is significantly faster.

  • --genesis-beacon-api-url=https://beaconstate.info provides the genesis state needed when using checkpoint sync.

  • --accept-terms-of-use accepts the Prysm terms of use non-interactively, which is required for the service to start without manual input.

Start and Enable the Prysm Service:
After saving the service file, reload the systemd daemon to apply the changes, start the Prysm service, and enable it to start on boot:

Command Line
sudo systemctl daemon-reload
sudo systemctl start prysm-beacon
sudo systemctl enable prysm-beacon
OutputCreated symlink /etc/systemd/system/multi-user.target.wants/prysm-beacon.service → /etc/systemd/system/prysm-beacon.service.

Check the Status of the Prysm Service:
Verify that Prysm is running correctly by checking its status:

Command Line
sudo systemctl status prysm-beacon
Output● prysm-beacon.service - Prysm Beacon Chain
     Loaded: loaded (/etc/systemd/system/prysm-beacon.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-03-23 08:43:05 UTC; 55s ago
   Main PID: 7254 (beacon-chain-v7)
      Tasks: 15 (limit: 76585)
     Memory: 5.3G (peak: 5.3G)
        CPU: 1min 17.189s
     CGroup: /system.slice/prysm-beacon.service
             ├─7254 /home/prysm-beacon/bin/prysm.sh --mainnet --datadir /home/prysm-beacon/beacon --execution-endpoint=http://127.0.0.1:8551 --jwt-secret=/var/lib/secr>
             └─7281 gpg-agent --homedir /home/prysm-beacon/.gnupg --use-standard-socket --daemon

Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.10]  INFO initial-sync: Starting initial chain sync...
Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.10]  INFO initial-sync: Waiting for enough suitable peers before syncing required=3 suitable=0
Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.14]  INFO p2p: Updating ENR Fork ID CurrentForkDigest=0x8c9f62fe NextForkDigest=0x8c9f62fe NextForkEpoch=1844>
Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.15]  INFO p2p: Started discovery v5 ENR=enr:-Ni4QJEiUFfyczFb3i1bwAXQf_BStHPen7_XdpIX8pdCz1cxP4vA-ODpZ1-QXUyXv>
Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.15]  INFO p2p: New node record ENR=enr:-Ni4QB10Ozb4KHFTwOAMUoyVeJ5tdwG6e3HB-RzndvnSzvU4CJy9E9ljkgHmUlCXrxl1vl>
Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.15]  INFO p2p: Node started p2p server multiAddr=/ip4/185.8.104.175/udp/13000/quic-v1/p2p/16Uiu2HAm8nuiGnzFs3>
Mar 23 08:43:24 demo prysm.sh[7254]: [2026-03-23 08:43:24.15]  INFO p2p: Node started p2p server multiAddr=/ip4/185.8.104.175/tcp/13000/p2p/16Uiu2HAm8nuiGnzFs3TBQfUYmu>
Mar 23 08:43:35 demo prysm.sh[7254]: [2026-03-23 08:43:35.00]  INFO p2p: Updating ENR Fork ID CurrentForkDigest=0x8c9f62fe NextForkDigest=0x8c9f62fe NextForkEpoch=1844>
Mar 23 08:43:39 demo prysm.sh[7254]: [2026-03-23 08:43:39.10]  INFO execution: Connected to new endpoint endpoint=http://127.0.0.1:8551
Mar 23 08:43:59 demo prysm.sh[7254]: [2026-03-23 08:43:59.20]  INFO blockchain: Called new payload with optimistic block parentRoot=0x649c54ee835b372db2f59eeffa4ea96b6>

You will see "Called new payload with optimistic block" in the status output. This is expected while Geth is still syncing. It means the beacon node is processing blocks but cannot fully verify them against Geth yet. It will clear once Geth finishes syncing.

You can quit with Ctrl + C. This won't affect the running service.

You can check the logs using:

Command Line
sudo journalctl -fu prysm-beacon
OutputMar 23 08:46:07 demo prysm.sh[7254]: [2026-03-23 08:46:07.88]  INFO blockchain: Finished applying state transition attestations=2 kzgCommitmentCount=7 payloadHash=0x73f01f7c6713 slot=13952626 syncBitsCount=512 txCount=364
Mar 23 08:46:07 demo prysm.sh[7254]: [2026-03-23 08:46:07.88]  INFO blockchain: Called fork choice updated with optimistic block finalizedPayloadBlockHash=0xce5c74ecdf84 headPayloadBlockHash=0x73f01f7c6713 headSlot=13952626
Mar 23 08:46:07 demo prysm.sh[7254]: [2026-03-23 08:46:07.89]  INFO blockchain: Called new payload with optimistic block parentRoot=0xf27cfcabb957cfe8e3bb0085f79726fb212acfbd9d9f269da2b21f8ace1592ce payloadBlockHash=0xa5b85c86e640 root=0xd34a5ee277448e04ad02535dea4097f6fd3a75c1297dba65fc8680665eb4ac9e slot=13952627
Mar 23 08:46:08 demo prysm.sh[7254]: [2026-03-23 08:46:08.07]  INFO blockchain: Synced new block block=0xd34a5ee2... epoch=436019 finalizedEpoch=436017 finalizedRoot=0x649c54ee... sinceSlotStartTime=21.073707889s slot=13952627

You should see Prysm connecting to the Geth client and syncing with the Ethereum blockchain. If the earlier message from Geth indicated that no beacon client was found, this step should resolve that, as Prysm will now be connected.

Geth relies on a consensus client like Prysm to determine the correct chain head. The clients split validation duties. Geth processes execution payloads, while the consensus client validates beacon blocks and attestations. Without a synced beacon client, Geth receives no new payloads, stalls, and falls out of sync.

Check Geth sync progress in another terminal:

Command Line
sudo journalctl -fu geth
OutputMar 23 09:01:20 demo geth[5092]: INFO [03-23|09:01:20.728] Syncing: chain download in progress      synced=12.55% chain=3.64GiB    headers=3,102,875@953.59MiB bodies=3,102,875@1.86GiB    receipts=3,102,875@869.88MiB eta=55m51.739s

Mar 23 09:01:22 demo geth[5092]: INFO [03-23|09:01:22.429] Syncing: state download in progress      synced=4.06%  state=15.42GiB  accounts=15,180,817@3.11GiB   slots=55,502,055@11.73GiB codes=120,532@591.43MiB eta=3h8m49.364s

Mar 23 09:01:24 demo geth[5092]: INFO [03-23|09:01:24.989] Forkchoice requested sync to new head    number=24,719,190 hash=5e8c62..18059a finalized=24,719,125

Syncing the execution client (Geth) can take several hours to days, depending on your internet speed and hardware. Monitor the synced percentage on both chain and state downloads. Once both reach 100%, Geth is fully synced, and the beacon node will exit optimistic mode. At that point, your Ethereum node is fully operational.

When Geth finishes syncing, the logs will change from sync progress lines to real-time block imports:

OutputMar 23 22:08:15 demo geth[5092]: INFO [03-23|22:08:15.432] Chain head was updated                   number=24,723,102 hash=a3cc41..f9685f root=d63746..58e26c elapsed=9.031602ms
Mar 23 22:08:25 demo geth[5092]: INFO [03-23|22:08:25.034] Imported new potential chain segment     number=24,723,103 hash=2ce780..fa1793 blocks=1         txs=282         mgas=18.790  elapsed=104.123ms    mgasps=180.455 triediffs=415.60MiB triedirty=202.97MiB
Mar 23 22:08:26 demo geth[5092]: INFO [03-23|22:08:26.480] Chain head was updated                   number=24,723,103 hash=2ce780..fa1793 root=5474b1..646e8b elapsed=2.910914ms

The beacon node will also exit optimistic mode. You will no longer see "optimistic block" in the Prysm logs:

OutputMar 23 22:07:38 demo prysm.sh[7254]: [2026-03-23 22:07:38.48]  INFO blockchain: Finished applying state transition attestations=5 consolidationRequestCount=1 kzgCommitmentCount=5 payloadHash=0xee15c3170d1d slot=13956636 syncBitsCount=511 txCount=430
Mar 23 22:07:49 demo prysm.sh[7254]: [2026-03-23 22:07:49.66]  INFO blockchain: Synced new block block=0x54923049... epoch=436144 finalizedEpoch=436142 finalizedRoot=0xf508c6c9... sinceSlotStartTime=2.665256933s slot=13956637

Your Ethereum node is now fully operational.

#How to Configure an Ethereum Validator Node with Prysm

After setting up your Ethereum node, you can run a validator node to help secure the network and earn rewards through the proof-of-stake mechanism.

Running a validator node involves:

  • Staking ETH: You need to stake at least 32 ETH to activate a validator, which acts as collateral to ensure honest behavior.

  • Constant uptime: Your validator must be online and connected to the network continuously to avoid penalties.

  • Security: You are responsible for securing your keys and protecting your node from attacks.

#Step 1: Download and verify the EthStaker Deposit CLI

First, download and verify the EthStaker Deposit CLI(ethstaker-deposit-cli). This tool will be used to create a validator keystore file used by your validator client and a deposit data file (deposit_data-*.json) used to activate your validator on the network

Download the latest release from the official repository.

You need to be online to perform the following verification step. After downloading the file, verify it using:

Command Line
gh attestation verify <filename> --repo eth-educators/ethstaker-deposit-cli

Replace <filename> with the full name of the file you downloaded, including the extension. For example: ethstaker_deposit-cli-b13dcb9-windows-amd64.zip on Windows or ethstaker_deposit-cli-b13dcb9-linux-amd64.tar.gz on Linux.

OutputLoaded digest sha256:e8e459c485b47195e93ca5ca5b3bebac9c17b7ddd5986e4bf922b768612ec90d for file://ethstaker_deposit-cli-b13dcb9-windows-amd64.zip Loaded 1 attestation from GitHub API
The following policy criteria will be enforced:
- Predicate type must match:................ https://slsa.dev/provenance/v1
- Source Repository Owner URI must match:... https://github.com/eth-educators
- Source Repository URI must match:......... https://github.com/eth-educators/ethstaker-deposit-cli
- Subject Alternative Name must match regex: (?i)^https://github.com/eth-educators/ethstaker-deposit-cli/
- OIDC Issuer must match:................... https://token.actions.githubusercontent.com

✓ Verification succeeded!

The following 1 attestation matched the policy criteria

- Attestation #1
    - Build repo:..... eth-educators/ethstaker-deposit-cli
    - Build workflow:. .github/workflows/build.yml@refs/tags/v1.2.2
    - Signer repo:.... eth-educators/ethstaker-deposit-cli
    - Signer workflow: .github/workflows/build.yml@refs/tags/v1.2.2

For detailed instructions on the installation and verification of the tool, refer to the official guide.

#Step 2: Create the validator keys

Next, you need to create the validator keys. It's recommended to perform this step on an offline and secure device to keep your mnemonic phrase safe.

Run the following command to create your validator keys. Replace NumberOfvalidators with the number of validator keys you want to create.

Command Line
deposit.exe new-mnemonic --num_validators=NumberOfvalidators --chain=mainnet

The tool will prompt you to set a password for your keystore and enter a withdrawal address. The withdrawal address cannot be changed once set on the chain. Make sure you have full control over the address you provide.

After setting your password, your mnemonic phrase will be displayed:

OutputThis is your mnemonic (seed phrase). Write it down and store it safely. It is the ONLY way to retrieve your deposit.

WARNING: You MUST write the mnemonic down, as the clipboard will be cleared after this step.

weird sphere genre eager snow fan minute ecology horn mom erupt age crew subject creek forward candy trip lens ship toward canal adapt client

Press any key when you have written down your mnemonic.

Write it down and store it securely offline. You will be asked to retype it to confirm before the tool creates your keys.

Once confirmed, your validator and deposit data files will be created.

OutputCreating your keys. Creating your keys: [####################################] 1/1 Creating your keystore-.json file(s): [####################################] 1/1 Creating your deposit_data-.json file(s): [####################################] 1/1 Verifying your keystore-.json file(s): [####################################] 1/1 Verifying your deposit_data-.json file(s): [####################################] 1/1

Success! Your keys can be found at: C:\Users\HP\Downloads\ethstaker_deposit-cli-b13dcb9-windows-amd64\validator_keys

Press any key.

validator and deposit data files

#Step 3: Create the validator client user

Next, on your server, create a user for the validator client and set up the necessary directories:

Command Line
sudo adduser --home /home/prysm-validator --disabled-password --gecos 'Prysm Validator Client' prysm-validator
sudo -u prysm-validator mkdir /home/prysm-validator/bin
sudo -u prysm-validator mkdir /home/prysm-validator/validator
Outputinfo: Adding user prysm-validator' ... 
info: Selecting UID/GID from range 1000 to 59999 ... 
info: Adding new group prysm-validator' (1005) ... 
info: Adding new user prysm-validator' (1005) with group prysm-validator (1005)' ... 
info: Creating home directory /home/prysm-validator' ... 
info: Copying files from /etc/skel' ... 
info: Adding new user prysm-validator' to supplemental / extra groups users' ... 
info: Adding user prysm-validator' to group users' ...

#Step 4: Download the Prysm.sh script

Now, download the Prysm.sh script for the validator client and make it executable:

Command Line
sudo -u prysm-validator curl https://raw.githubusercontent.com/OffchainLabs/prysm/master/prysm.sh --output /home/prysm-validator/bin/prysm.sh
sudo -u prysm-validator chmod +x /home/prysm-validator/bin/prysm.sh

This is the same script used by the beacon node, configured here specifically for the validator client.

#Step 5: Import the validator keys

First, securely transfer the validator keys to the server and the appropriate permissions for the directory, making the Prysm validator user the owner.

Transfer the keys:

Command Line
scp -r validator_keys <user>@<server-ip>:/home/prysm-validator

Replace <user> with your username and <server-ip> with your server's IP address.

Change ownership and permissions:

Command Line
sudo chown -R prysm-validator:prysm-validator /home/prysm-validator/validator_keys
sudo chmod 750 /home/prysm-validator/validator_keys

With the validator_keys directory now on the server, import the keys into the Prysm validator client using:

Command Line
sudo -u prysm-validator /home/prysm-validator/bin/prysm.sh validator accounts import --keys-dir=/home/prysm-validator/validator_keys --mainnet

The tool will download and verify the validator binary, then walk you through setting up a wallet and importing your keys. After accepting the terms of service presented, you'll be asked to input a wallet password. After confirming the password, a new wallet will be created at the default wallet location (/home/prysm-validator/.eth2validators/prysm-wallet-v2).

Then you'll be asked to provide the password for your imported accounts. This is the password you set when creating the validator keys in Step 2. If the password is correct, the keys will be imported successfully.

OutputDownloading validator@v7.1.3 to /home/prysm-validator/bin/dist/validator-v7.1.3-linux-amd64
...
Verifying binary integrity.
gpg: key 72E33E4DF1A5036E: public key "Preston Van Loon <preston@pvl.dev>" imported
gpg: Good signature from "Preston Van Loon <preston@pvl.dev>" [unknown]
Primary key fingerprint: 0AE0 051D 647B A3C1 A917 AF40 72E3 3E4D F1A5 036E
Verified /home/prysm-validator/bin/dist/validator-v7.1.3-linux-amd64 has been signed by Prysmatic Labs.

Prysm Terms of Use
...
Type "accept" to accept this terms and conditions [accept/decline]: (default: decline): accept 

[2026-03-23 09:34:17.72] INFO flags: Running on Ethereum Mainnet
Enter a wallet directory (default: /home/prysm-validator/.eth2validators/prysm-wallet-v2):
Password requirements: at least 8 characters
New wallet password: 
Confirm password: 
[2026-03-23 09:42:50.95] INFO wallet: Successfully created new wallet
[2026-03-23 09:42:50.95] INFO accounts: checking directory for keystores: /home/prysm-validator/validator_keys
Enter the password for your imported accounts: 
Importing accounts... 100% [================================================] 
[2026-03-23 09:43:04.76] INFO local-keymanager: Successfully imported validator key(s)
[2026-03-23 09:43:04.76] INFO accounts: Imported accounts [b1e787bbb...], view all of them by running accounts list

Next, change the ownership of the .eth2validators/prysm-wallet-v2 directory and all its contents to the prysm-validator user.

Command Line
sudo chown -R prysm-validator:prysm-validator /home/prysm-validator/.eth2validators/prysm-wallet-v2

#Step 6: Secure the wallet password

Create a text file that only the validator can access to store the wallet password:

Command Line
sudo -u prysm-validator touch /home/prysm-validator/password.txt
sudo chmod 600 /home/prysm-validator/password.txt

The validator service needs this password to decrypt the keystore on startup without requiring manual input.

Edit the file and store the wallet password that you created when importing the validator keys:

Command Line
sudo nano /home/prysm-validator/password.txt

#Step 7: Create a systemd service for the validator client

Next, create a systemd service file to manage the Prysm validator client.

Open the service file using the Nano text editor:

Command Line
sudo nano /etc/systemd/system/prysm-validator.service

Paste the following configuration:

[Unit]

Description=Prysm Validator Client
Wants=prysm-beacon.service
After=prysm-beacon.service
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=5
User=prysm-validator
ExecStart=/home/prysm-validator/bin/prysm.sh validator \
  --datadir=/home/prysm-validator/validator \
  --wallet-dir=/home/prysm-validator/.eth2validators/prysm-wallet-v2 \
  --wallet-password-file=/home/prysm-validator/password.txt \
  --suggested-fee-recipient=YourWalletAddress \
  --graffiti="YourGraffiti" \
  --beacon-rpc-provider=127.0.0.1:4000 \
  --accept-terms-of-use

[Install]
WantedBy=multi-user.target
  • --mainnet connects the validator to the Ethereum mainnet.

  • --datadir=/home/prysm-validator/validator sets the directory where the validator stores its data.

  • --wallet-dir=/home/prysm-validator/.eth2validators/prysm-wallet-v2 points to the wallet you created when importing the keys.

  • --wallet-password-file=/home/prysm-validator/password.txt provides the wallet password file you created in Step 6.

  • --beacon-rpc-provider=127.0.0.1:4000 points the validator to the local beacon node.

  • --suggested-fee-recipient=YourWalletAddress should be replaced with your Ethereum wallet address to receive potential rewards.

  • --graffiti is used to add a custom text to the validator’s blocks.

  • --accept-terms-of-use accepts the Prysm terms of use non-interactively, allowing the service to start automatically.

Start and Enable the Validator Service:

Finally, start the validator service and ensure it starts on boot:

Command Line
sudo systemctl daemon-reload
sudo systemctl start prysm-validator
sudo systemctl enable prysm-validator
OutputCreated symlink /etc/systemd/system/multi-user.target.wants/prysm-validator.service → /etc/systemd/system/prysm-validator.service.

Check the logs to ensure both the Beacon Chain and Validator services are running properly:

Command Line
sudo journalctl -fu prysm-validator
OutputMar 23 22:01:59 demo prysm.sh[14823]: [2026-03-23 22:01:59.07] INFO client: Waiting for deposit to be observed by beacon node pubkey=0xb1e787bbb4cd status=UNKNOWN_STATUS 
Mar 23 22:01:59 demo prysm.sh[14823]: [2026-03-23 22:01:59.07] WARN client: No active validator keys provided. Waiting until next epoch to check again... seconds_until_next_epoch=384 
Mar 23 22:08:23 demo prysm.sh[14823]: [2026-03-23 22:08:23.07] INFO client: Waiting for deposit to be observed by beacon node pubkey=0xb1e787bbb4cd status=UNKNOWN_STATUS 
Mar 23 22:08:23 demo prysm.sh[14823]: [2026-03-23 22:08:23.07] WARN client: No active validator keys provided. Waiting until next epoch to check again... seconds_until_next_epoch=384

From the logs or status, you should see the message "Waiting for deposit to be observed by beacon node." This occurs because the validator has not yet been activated on the network.

#Step 8: Upload the deposit and activate the validator

To activate your validator, go to the Ethereum Mainnet Launchpad. Select "Become a Validator," and follow the prompts until you reach the step where you need to upload your deposit data file (deposit_data-*.json). Connect your wallet with at least 32 ETH, review and confirm the details, then deposit the ETH into the Ethereum deposit contract. After confirmation, monitor your validator to ensure the beacon node recognizes it and is operating correctly.

Once activated, your validator will help verify and confirm transactions and, occasionally, propose new blocks on the Ethereum network. This participation supports network security and functionality, and you’ll earn rewards for performing the tasks correctly.

Latency from 30ms to 5ms with Cherry Servers

Read how ELSOUL LABO, leading Solana RPC provider, reduced latency from 30 ms to 5 ms with Cherry Servers' high-performance dedicated bare metal, ensuring optimal performance for their users.

#Conclusion

At this point, your Ethereum node should be running, or you now understand the full setup process. You configured both the execution client with Geth and the consensus client with Prysm, and you saw how to set up a validator node.

Running your own node supports the network’s decentralization and security. If you choose to run a validator, you also earn rewards for participating. From here, focus on monitoring your node, keeping your clients updated, and maintaining uptime.

Paying too much for cloud infrastructure?

Switch to blockchain-optimized dedicated bare metal—save up to 60% on your cloud bill and double the performance compared to hyperscale cloud.

Blockchain Servers – Built for Web3

Deploy secure and high-performance nodes on dedicated infrastructure.

Share this article

Related Articles

Published on May 11, 2026 Updated on May 19, 2026

What is MEV in Blockchain: Infrastructure & Cross-Chain Strategies

Learn what MEV (Maximal Extractable Value) in blockchain is, how cross-chain MEV works, and why dedicated nodes, low latency, and reliable infrastructure matter for MEV execution.

Read More
Published on Apr 29, 2026 Updated on Apr 30, 2026

Does Hetzner Accept Crypto [7 Hetzner Alternatives to Consider]

Does Hetzner accept crypto payments? In this guide, we’ll answer that question directly and explore the best crypto-friendly Hetzner alternatives.

Read More
Published on Apr 27, 2026 Updated on Apr 28, 2026

How To Create an ERC20 Token: Step-by-Step

This guide walks you through how to create an ERC20 token. You'll learn ERC20 standards, costs, and deploy your token using Remix, Hardhat, and Foundry on Ethereum.

Read More
No results found for ""
Recent Searches
Navigate
Go
ESC
Exit