Skip to main content

Connect your execution client

Prysm needs an execution layer client (EL), such as Geth or Nethermind, running alongside it; the EL checks transactions in every block. The two connect on port 8551 by default and prove who they are with a shared secret file, the JWT secret.

Operating system
Network
Execution client
Engine API connection

Before you begin​

  • The Prysm launcher script and a folder for each program and for the data. The programs live in consensus and execution, and everything the clients store goes into data, one folder per network. The commands on this page use this layout:

    ~/ethereum/
    ├── consensus/
    ├── execution/
    └── data/
    └── mainnet/
    ├── execution/
    └── beacon/

    If you don't have it yet, create the folders, then download the Prysm launcher script into consensus:

    mkdir -p $HOME/ethereum
    cd $HOME/ethereum

    mkdir -p \
    consensus \
    execution \
    data/mainnet/execution \
    data/mainnet/beacon

    cd consensus
    curl https://raw.githubusercontent.com/OffchainLabs/prysm/master/prysm.sh --output prysm.sh && chmod +x prysm.sh

    See Install Prysm for the other install methods and for verifying the download.

  • Enough disk space for the EL. See System requirements.

Connect the two clients​

  1. Create the JWT secret. Do this once. Both clients read the same file.

    cd ~/ethereum/consensus
    ./prysm.sh beacon-chain generate-auth-secret --output-file=$HOME/ethereum/data/jwt.hex

    Prysm prints:

    INFO jwt: Successfully wrote JSON-RPC authentication secret to file /home/<USER>/ethereum/data/jwt.hex

    The file is readable only by you (0600).

    The file holds 64 hex characters, and the same secret serves every network. Running the command again replaces the secret, so don't; you'd have to restart both clients with the new file.

  2. Install and start your execution client. The commands keep the EL's data in ethereum/data, in the folder for your network.

    Install: see the Besu installation guide. Besu needs Java 25 or later.

    To start it:

    besu \
    --network=mainnet \
    --data-path=$HOME/ethereum/data/mainnet/execution \
    --engine-jwt-secret=$HOME/ethereum/data/jwt.hex

    Besu gives the JVM 25% of RAM by default; its memory guide suggests this on machines with 24 GB or more:

    export BESU_OPTS=-Xmx8g

    Always give the EL an absolute path to the secret. Most clients create a new secret when the path doesn’t exist, and Prysm then doesn’t know it.

  3. Start the beacon node from the consensus folder:

    ./prysm.sh beacon-chain \
    --mainnet \
    --datadir=$HOME/ethereum/data/mainnet/beacon \
    --execution-endpoint=http://localhost:8551 \
    --jwt-secret=$HOME/ethereum/data/jwt.hex \
    --checkpoint-sync-url=https://sync-mainnet.beaconcha.in \
    --beacon-db-pruning

    At startup, Prysm logs:

    INFO execution: Finished reading JWT secret from /home/<USER>/ethereum/data/jwt.hex

    The checkpoint sync URL is one of several community endpoints; any one you trust works.

    --beacon-db-pruning deletes blocks and states older than about five months; the oldest data other nodes can still ask for, so the database stops growing. Leave it out if you need the full history.

    Running validators? Also add:

    --postpone-shutdown-for-proposals

    When you stop or restart the beacon node, it then waits until your validators' upcoming block proposals are done. For more information refer to the Don't restart just before a proposal page.

The two flags that matter:

FlagDefaultWhat to set
--execution-endpointhttp://localhost:8551The EL's Engine API address. Leave the default when the EL runs on the same machine with default ports.
--jwt-secretnonePath to the same JWT secret file the EL uses.
Never expose port 8551 to the internet

The JWT secret is the only protection on the Engine API. Allow port 8551 only from the beacon node's address.

Check that it works​

  1. Ask the beacon node whether it reaches the EL:

    curl -s http://127.0.0.1:3500/eth/v1/node/syncing

    "el_offline":false means the connection works. "is_optimistic":true means the EL is still syncing; that's normal for the first hours. Once it shows false, the EL has caught up.

  2. Watch the beacon node logs. Once both are synced, Prysm logs a Synced new block line for every block. While the EL is still catching up, you see Called fork choice updated with optimistic block instead.

Troubleshooting​

Authentication fails. Prysm logs one of:

HTTP authentication to your execution client is not working
401 Unauthorized

Prysm and the EL read different secrets. Check the EL's startup log for the path it loaded; a line such as Geth's Generated JWT secret or Nethermind's ...was not found or was empty, so it has been automatically created means the path was wrong and the EL made its own. Point both at the same file and restart both. Also check that the clocks are in sync.

The chain IDs don't match. Prysm logs, with your networks' chain IDs:

wanted chain ID 560048, got 1

The two clients are on different networks; here, Prysm is on Hoodi and the EL on mainnet. Start both on the same network.

Prysm can't read the JWT secret. Prysm logs:

could not read JWT secret file for authenticating execution API

Prysm can't read the file, or it doesn't hold exactly 32 bytes of hex. Check the path and permissions.

The EL logs that no beacon client or consensus client is connected. Prysm isn't running, points at the wrong port, or fails authentication. Check the beacon node logs.

The beacon node stays optimistic. The EL is still syncing. That can take hours or days. If it never progresses, check the EL's peers and disk speed.