---
title: Running a validator on Stokenet after the 2026-08-29 reset
version: 1.2
date: 2026-09-13
audience: community node operators
supersedes: 1.1 (2026-09-09) — the v1.3.0.5 patch procedure is removed entirely
---

# Running a Stokenet validator after the reset

Stokenet was reset on **2026-08-29**. A brand-new chain was created with a new genesis, and the
old chain is frozen — it still exists, nodes still gossip on it, but it will never advance.

Everything in the official Radix documentation still applies. There are exactly **three things
that differ**, and this document covers only those:

1. Run **`radixdlt/babylon-node:v1.4.0.0`** (Eagle Ray) or later. It is the **stock public image —
   no patch, no local build.** Older versions cannot follow this chain.
2. You must supply the new **`genesis.bin`** and point the node at it.
3. You need **test XRD** to create and stake a validator, since the reset destroyed all balances.

> **If you ran a Stokenet node before 2026-08-29, wipe your ledger database.** An existing
> database is the old chain. Keeping it is the single most common way to end up quietly
> validating nothing.

> **Earlier versions of this handout told you to patch a `v1.3.0.5` image. Ignore that.** RDX
> compiled this chain's genesis into the release from `v1.4.0.0-RC1` onward, so the patched jar,
> the `Dockerfile` and the `docker build` step are all retired. If you already run a patched
> image, change the `image:` line to `radixdlt/babylon-node:v1.4.0.0`, remove anything that
> injects the old jar, and keep everything else.

---

## Step 0 — Do the standard setup first

Follow the normal Radix node documentation to provision the server, install Docker, generate
your node keystore, and lay out the compose file:

<https://docs.radixdlt.com/docs/node-setup-introduction>

Stop before you start the node. Then apply the changes below.

**Requirements beyond the standard docs:**

| Item | Requirement |
|---|---|
| Node version | `v1.4.0.0` or later — stock image |
| Docker Compose | **v2** (`docker compose`, not `docker-compose`) — see Troubleshooting |
| Inbound port | `30000/tcp` reachable from the internet |

---

## Step 1 — Pull the image

```bash
docker pull radixdlt/babylon-node:v1.4.0.0
docker buildx imagetools inspect radixdlt/babylon-node:v1.4.0.0 | grep -m1 Digest
```

Expected index digest (Docker Hub, published 2026-09-10):

```
sha256:46a50a6c508906d63df2b142d794a3fb0e38269e9e130d5d4ca5b67f827d16f4
```

> The tag has **four** version components. `v1.4.0` does not exist and will not pull.

---

## Step 2 — Get the genesis file

```bash
mkdir -p ~/radix-node/genesis && cd ~/radix-node/genesis
curl -fLO https://stokenet.ams3.digitaloceanspaces.com/instructions/genesis.bin
sha256sum genesis.bin
```

```
genesis.bin   669 bytes
sha256: 0006347310c9d155fe4d625f1317e86e43bd3a550d2be2b656a2968163f95108
```

**Check this hash.** The frozen old chain has a different genesis of exactly the same size. If it
does not match, stop.

The release already knows this genesis, so why supply the file? Because the node cross-checks
the genesis in your file, the one compiled into the release and the one in your database, and
refuses to start unless all of them agree. With the file present, a clean start proves you are on
the right chain. That is the configuration we run and tested.

Stage it outside `/tmp` — `/tmp` does not survive a reboot.

---

## Step 3 — Compose changes

```yaml
    image: radixdlt/babylon-node:v1.4.0.0
    environment:
      RADIXDLT_NETWORK_ID: 2
      RADIXDLT_HOST_IP_ADDRESS: "<your node's public IP>"
      RADIXDLT_GENESIS_DATA_FILE: "/genesis/genesis.bin"
      RADIXDLT_NETWORK_SEEDS_REMOTE: >-
        radix://node_tdx_2_1q2237aq4h3h9xxghx4x4l5h3sg0awl058t247z7jhq5geahe00hax75wcds@193.200.238.146,
        radix://node_tdx_2_1qfhupcz3wlexlk3ghe7rq2dfe8ayyl8zzrdrzg8a7z0swckmwxzav4vklmd@193.200.238.147,
        radix://node_tdx_2_1qfaxgqj0nq355827uchzu8fszg24ttktw7khew4hhcsqgd03d7lauzk59jm@193.200.238.148
      # Validator profile — see below
      RADIXDLT_DB_KEEP_PREVIOUS_SUBSTATE_VALUES: "false"
    volumes:
      - babylon_ledger:/home/radixdlt/RADIXDB
      - ./node-keystore.ks:/home/radixdlt/node-keystore.ks
      - ./genesis:/genesis
```

Both the genesis env var **and** the volume mount are required. Without the env var the node
ignores the file; without the mount the path does not exist.

**Set `RADIXDLT_HOST_IP_ADDRESS` to your real public IP.** Leaving it unset has caused nodes to
fail to accept inbound peers.

### Database settings — state them explicitly

The image builds its config by substituting environment variables into a template, and a
variable you do not set can become an empty string rather than the documented default. So be
explicit about the settings that matter:

**`RADIXDLT_DB_KEEP_PREVIOUS_SUBSTATE_VALUES`**

- **Validator only → `"false"`.** A validator needs consensus, not the previous value of every
  substate change. This is the biggest single disk saving — on mainnet a ledger synced from
  genesis with it off is roughly 460 GB instead of 750 GB. All of our Stokenet validators run
  `"false"`.
- **Serving a Gateway, or anything that reads history via the Core API → `"true"`.** The Gateway
  needs this data, and whatever the node commits while the setting is off is never written, so
  it cannot be recovered without a resync.

This setting can be changed at any time with a restart — it only affects what is written from
then on.

**Do not set `RADIXDLT_ENTITY_LISTING_INDICES_ENABLE`.** Leave it out entirely. When it is set,
startup can replay every receipt from a stale state version for minutes, which looks exactly
like a hang you would be tempted to kill.

**Optional, for an even leaner validator** — decide these **before your first sync**. Whether
turning them off on an existing database needs a resync has not been verified:

```yaml
      RADIXDLT_DB_LOCAL_TRANSACTION_EXECUTION_INDEX_ENABLE: "false"
      RADIXDLT_DB_ACCOUNT_CHANGE_INDEX_ENABLE: "false"
```

There is no ledger snapshot to restore. The chain is young, so syncing from scratch is fast.

### You do not need any protocol-update configuration

The protocol updates are enacted on this chain by on-ledger validator readiness signalling. Your
node re-derives them from the ledger as it syncs. **Do not set `RADIXDLT_PROTOCOL_CUSTOM_CONFIG`**
— a config that disagrees with the ledger makes the node refuse to start.

---

## Step 4 — Start and confirm you are on the right chain

```bash
docker compose -f <your compose file> up -d
docker ps --format '{{.Names}}'          # note your core container's name
```

Check startup with a **filtered** log read:

```bash
docker logs <core container> 2>&1 | grep -E "Radix distributed ledger|genesis|Inconsistent"
```

> **Never paste unfiltered `docker logs` output anywhere.** The entrypoint prints its whole
> environment at startup, including your keystore password.

A correct start shows:

```
Radix distributed ledger 'v1.4.0.0' ...
Loading genesis from file: /genesis/genesis.bin
Using a genesis of hash 2536c14ce79bb6cf7113aeed00a76666c4693622ee2187fefdf5225a2fd5cd51
```

and **no** `Inconsistent genesis configuration`.

Then confirm the protocol state:

```bash
docker exec <core container> curl -s http://127.0.0.1:3334/system/health \
  | jq '{status, current_protocol_version,
         pending: [.pending_protocol_updates[] | {protocol_version, readiness_signal_name}]}'
```

You should see either `current_protocol_version: "eagle-ray"`, or `"cuttlefish-part2"` with
`eagle-ray` listed under `pending`. Anything older means the node is still syncing, or you are on
the wrong chain.

Compare your state version against the public gateway — you should be catching up toward it:

```bash
curl -s -X POST https://gateway-stokenet.radix.community/status/gateway-status \
  -H 'Content-Type: application/json' -d '{}'
```

---

## Step 5 — Get test XRD

The reset destroyed all balances, so there is no XRD in your account and the faucet will not
give you enough to create a validator.

### Contact **@Doelle_Doeck on Telegram** for test XRD for staking.

<https://t.me/Doelle_Doeck>

Have ready:

- your Stokenet account address (`account_tdx_2_…`)
- roughly how much stake you want

Budget a couple of thousand XRD for the validator creation fee (it is priced at about 100 USD
worth of XRD), plus whatever you intend to stake.

---

## Step 6 — Create, register and stake your validator

This part is entirely standard Radix — nothing about the reset changes it. Use the Radix
Dashboard, or submit a manifest directly. Point any tooling at
`https://gateway-stokenet.radix.community`.

You need your **node public key**, which is available from:

```bash
docker exec <core container> curl -s http://127.0.0.1:3334/system/identity
```

A manifest that creates the validator:

```
CALL_METHOD
    Address("<your account>")
    "withdraw"
    Address("resource_tdx_2_1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxtfd2jc")
    Decimal("2000");
TAKE_FROM_WORKTOP
    Address("resource_tdx_2_1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxtfd2jc")
    Decimal("2000")
    Bucket("validator_creation_fee");
CREATE_VALIDATOR
    Bytes("<your node public key, hex>")
    Decimal("1")
    Bucket("validator_creation_fee");
CALL_METHOD
    Address("<your account>")
    "try_deposit_batch_or_abort"
    Expression("ENTIRE_WORKTOP")
    None;
```

The `Decimal("1")` is the fee factor, between 0 and 1: your cut of emissions. Any unused part of
the 2000 XRD comes back to your account.

That returns a **validator owner badge** to your account and creates your validator component.
Read the new `validator_tdx_2_…` address out of the transaction receipt, then in a second
transaction — using a proof of that owner badge — call `register` and
`update_accept_delegated_stake true`, set your metadata, and `stake` your XRD.

### Then tell your node which validator it is

A newly created validator is **not** in genesis, so add its address explicitly:

```yaml
      RADIXDLT_CONSENSUS_VALIDATOR_ADDRESS: "validator_tdx_2_<yours>"
```

> Do **not** set `RADIXDLT_CONSENSUS_USE_GENESIS_FOR_VALIDATOR_ADDRESS`. That flag is only for
> validators that exist in genesis; on a newly created validator it finds nothing and your node
> will run without validating.

Restart with `docker compose -f <your compose file> down --timeout 120` then `up -d`. Do not use
`docker compose start`, which ignores compose changes. The `--timeout 120` lets RocksDB close
cleanly. You join the active validator set at the next epoch boundary (about 5 minutes), provided
your stake places you in the top 100.

Confirm you are validating:

```bash
docker exec <core container> curl -s http://127.0.0.1:3334/system/health | jq .
```

### If eagle-ray is still pending — signal readiness

If Step 4 showed `eagle-ray` under `pending`, it enacts only once validators holding **80% of
stake** signal readiness for 10 consecutive epochs. Your owner badge is in your own account, so
**only you can signal for your validator**, and with enough stake your silence can hold up
enactment for everyone. Once you are registered and staked:

```
CALL_METHOD
    Address("<your account>")
    "create_proof_of_non_fungibles"
    Address("<validator owner badge resource address>")
    Array<NonFungibleLocalId>(
        NonFungibleLocalId("<your owner badge local id>")
    );
CALL_METHOD
    Address("validator_tdx_2_<yours>")
    "signal_protocol_update_readiness"
    "8ed71bbdf45861cb0000000eagle-ray";
```

Take the badge's resource address and local id from your account in the wallet or the gateway,
and take the signal string from your own node's `readiness_signal_name` (Step 4) rather than
trusting this page. If `current_protocol_version` is already `eagle-ray`, skip this section.

---

## Troubleshooting

| Symptom | Cause | Fix |
|---|---|---|
| `Inconsistent genesis configuration` | wrong `genesis.bin`, old ledger database, or a pre-1.4 / patched image | check the genesis sha256 and the image tag; wipe the DB only if it is from the old chain |
| Node syncs a chain that never advances | old ledger database retained | wipe the ledger volume and restart |
| Node runs but never validates | validator address not set, or the genesis flag used instead | set `RADIXDLT_CONSENSUS_VALIDATOR_ADDRESS` |
| Startup appears to hang, logging `Entity listing indices updated to …` | `RADIXDLT_ENTITY_LISTING_INDICES_ENABLE` is set | remove it, restart |
| Compose change had no effect | `docker compose start` / `restart` used | `down --timeout 120` then `up -d` |
| `KeyError: 'ContainerConfig'` or `KeyError: 'id'` | Docker Compose v1 | `sudo apt install -y docker-compose-plugin`, use `docker compose` |
| `No valid address available for peer` | stale seed list | use the seed list in Step 3 |

---

## Network reference

| Item | Value |
|---|---|
| Network | Stokenet, network id 2, HRP `tdx_2_` |
| Chain start | 2026-08-29 11:22 UTC |
| Node image | `radixdlt/babylon-node:v1.4.0.0` (stock) |
| Image index digest | `sha256:46a50a6c508906d63df2b142d794a3fb0e38269e9e130d5d4ca5b67f827d16f4` |
| Genesis hash (as logged) | `2536c14ce79bb6cf7113aeed00a76666c4693622ee2187fefdf5225a2fd5cd51` |
| `genesis.bin` sha256 | `0006347310c9d155fe4d625f1317e86e43bd3a550d2be2b656a2968163f95108` |
| `genesis.bin` download | <https://stokenet.ams3.digitaloceanspaces.com/instructions/genesis.bin> |
| Public gateway | `https://gateway-stokenet.radix.community` |
| P2P port | `30000/tcp` |
| Epoch length | ~5 minutes |
