IoTeX Node Setup & Upgrade Guide for AI Agents

April 15, 2026 · View on GitHub

Practical knowledge for AI agents setting up or upgrading an IoTeX mainnet fullnode. Covers pitfalls not obvious from the main README.

Prerequisites

  1. Docker — must be installed first. The setup script checks but does NOT install it:

    curl -fsSL https://get.docker.com | sh
    
  2. docker-compose standalone binary — the script requires docker-compose (not docker compose plugin syntax). Modern Docker ships the plugin but not the standalone binary:

    ln -sf /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose
    
  3. Non-root user (recommended) — install Docker as root, then create a node user with docker group access:

    useradd -m -s /bin/bash <username>
    usermod -aG docker <username>
    

Fresh Install

Before you start

  1. Check available disk space — first check the actual snapshot size, then compare against free disk:
    # Step 1: Check current compressed snapshot size (as of 2026-04, ~182GB compressed, ~265GB extracted)
    curl -sIL https://t.iotex.me/mainnet-data-snapshot-core-latest 2>/dev/null | grep -i content-length
    # Step 2: Check free disk on all partitions
    df -h
    
    • These sizes grow over time — always check the URL first, don't rely on the numbers above.
    • Core node: extracted size + growth headroom (as of 2026-04, ~300GB minimum). Gateway node: 1TB+.
    • If using stream extraction (curl | tar), only the extracted size is needed. If downloading tarball first, both compressed + extracted sizes are needed.
    • If no single partition is large enough, tell the user to resize the disk or attach additional storage before proceeding.
  2. Choose the install path — pick the partition with the most space. Recommend $HOME/iotex-var if the home partition is large enough, otherwise use the largest mounted volume (e.g., /data/iotex-var, /mnt/iotex-var). Ask the user if unclear.

Run the setup

# Download the setup script — note: it's under scripts/, NOT repo root
curl -sSL https://raw.githubusercontent.com/iotexproject/iotex-bootstrap/master/scripts/setup_fullnode.sh -o ~/setup_fullnode.sh

See the main README for all available flags.

Fresh installs need snapshot data. Without it, the node tries to sync from genesis using an Ethereum RPC endpoint. The default Infura key in config.yaml is expired, so the node will crash with 401 Unauthorized: account disabled. There are two ways to get the snapshot data:

  • Option A: Let the script download it (--snapshot). Simple, but downloads the tarball to $IOTEX_HOME/tmp/ on the same partition, so you need enough disk for both compressed + extracted data.
    bash ~/setup_fullnode.sh --auto --home=<install-path> --snapshot
    
  • Option B: Download the snapshot manually first (recommended). Supports resume on failure and lets you use a separate disk/volume for the tarball. After extracting to $IOTEX_HOME/data/, run the script without --snapshot — it detects existing data automatically.
    # 1. Download and extract (see "Snapshot download" below for details)
    # 2. Then run setup without --snapshot
    bash ~/setup_fullnode.sh --auto --home=<install-path>
    

Key things to know

  • Fresh install in --auto mode now works without interactive prompts:
    • externalHost is auto-detected via curl -4 ip.sb (forced IPv4 — p2p layer does not handle IPv6).
    • A random producerPrivKey is auto-generated as a temporary operator wallet.
    • After install, ask the user: "A temporary operator key was generated. Do you want to fund this wallet for staking, or replace it with an existing key in $IOTEX_HOME/etc/config.yaml?"
  • externalHost must be IPv4. The script now uses curl -4 ip.sb by default. If the detected IP is wrong, update $IOTEX_HOME/etc/config.yaml and restart.
  • Snapshot download details: The compressed snapshot is ~182GB and extracts to ~265GB (as of 2026-04) — these sizes grow over time, always verify by checking the URL as shown above.
    • Option A (--snapshot) downloads to $IOTEX_HOME/tmp/ on the same partition. Needs enough disk for compressed + extracted data. No resume on failure.
    • Option B (manual, recommended): Download the tarball yourself — supports resume and separate disk/volume:
      apt-get install -y pigz
      mkdir -p $IOTEX_HOME/data
      # Download with resume support (use a separate disk/volume if main disk is too small)
      DOWNLOAD_DIR=$IOTEX_HOME  # or /mnt/volume if main disk can't hold both
      until curl -L -C - -o $DOWNLOAD_DIR/snapshot.tar.gz \
        --retry 20 --retry-delay 10 --speed-limit 100000 --speed-time 120 \
        https://t.iotex.me/mainnet-data-snapshot-core-latest; do
        echo "Download interrupted, resuming in 30s..."; sleep 30
      done
      # Extract with parallel decompression, then clean up
      pigz -dc $DOWNLOAD_DIR/snapshot.tar.gz | tar -xf - -C $IOTEX_HOME/data/
      rm -f $DOWNLOAD_DIR/snapshot.tar.gz
      
      Highly recommended: use aria2c instead of curl — 5x to 15x faster in practice (measured ~275 MB/s with aria2c vs ~17 MB/s with single-connection curl). It splits the download across multiple parallel connections and also supports resume:
      apt-get install -y aria2 pigz
      mkdir -p $IOTEX_HOME/data
      DOWNLOAD_DIR=$IOTEX_HOME  # or /mnt/volume if main disk can't hold both
      aria2c -x 16 -s 16 -k 10M --continue=true \
        --max-tries=20 --retry-wait=10 \
        -o snapshot.tar.gz -d $DOWNLOAD_DIR \
        https://t.iotex.me/mainnet-data-snapshot-core-latest
      pigz -dc $DOWNLOAD_DIR/snapshot.tar.gz | tar -xf - -C $IOTEX_HOME/data/
      rm -f $DOWNLOAD_DIR/snapshot.tar.gz
      
    • Stream extraction (fallback — only when disk is very constrained): Pipe curl directly into tar — no intermediate file, but cannot resume on failure. Only use when you truly cannot attach a temporary volume:
      apt-get install -y pigz
      mkdir -p $IOTEX_HOME/data
      # No resume — restarts from scratch on failure
      ATTEMPT=0; MAX=5
      until [ $ATTEMPT -ge $MAX ]; do
        ATTEMPT=$((ATTEMPT + 1)); echo "Attempt $ATTEMPT/$MAX"
        rm -rf $IOTEX_HOME/data/*
        curl -L -s --retry 10 --retry-delay 5 --speed-limit 100000 --speed-time 60 \
          https://t.iotex.me/mainnet-data-snapshot-core-latest | pigz -d | tar -xf - -C $IOTEX_HOME/data/ && break
        echo "Failed, retrying in 30s..."; sleep 30
      done
      
  • Disk space: always verify the current snapshot size from the URL before proceeding. Ensure the target partition has enough free space plus growth headroom. If the main disk can't hold both the compressed and extracted data, attach a temporary volume for the download — it only needs to hold the compressed file and can be deleted after extraction. If the target partition is too small even for extracted data, suggest the user resize the disk before proceeding.

Upgrade

bash ~/setup_fullnode.sh --auto --home=$HOME/iotex-var

Upgrades preserve externalHost, producerPrivKey, and adminPort. No snapshot download needed — only the binary and configs are updated. Downtime is minimized by pulling the new image before stopping the old container.

Verify

docker ps | grep iotex
docker logs -f --tail 20 iotex | grep -E "height|sync|error"

The node is healthy when block heights are increasing with no fatal errors.

Ports

PortPurposeRequired
4689P2P networkAlways
8080HTTP statsAlways
14014gRPC APIGateway only
15014Ethereum JSON-RPC APIGateway only
16014Ethereum WebSocketGateway only