Skip to main content

Run a split validator node

Running split validators for Arbitrum chains

Split validators separate the validation work to a stateless validation node, which provides several key benefits:

  • Resource management: Easier to scale and manage compute resources independently
  • Fault isolation: Prevents database corruption if the validation node crashes (e.g., due to OOM errors)
  • Flexibility: Allows running multiple validation nodes for horizontal scalability

This guide explains how to set up a split validator configuration for Arbitrum chains by running a Nitro node (bonder) and a validation node separately.

Before you read this doc, please ensure you have already walked through run a validator docs to understand the basics of a validator node.

What is AUTH-RPC and the validation API

Nitro nodes can expose two separate WebSocket RPC interfaces:

  • The public RPC (configured under --http.* and --ws.*) serves the standard eth_, net_, and other namespaces that wallets and dApps use.
  • AUTH-RPC (configured under --auth.*) is a second, JWT-authenticated WebSocket interface intended for trusted intra-component communication. It listens on its own address and port and by default exposes only the validation namespace.

The validation_* namespace is how the bonder delegates WASM execution to the validation node—it carries Validate (run the WASM machine on a prepared input and return the resulting global state) plus CreateExecutionRun, GetStepAt, and GetProofAt (used during challenges to fetch step hashes and one-step proofs). The full method list is in the validation_* API reference below.

The rest of this guide walks through the deployment; the API reference and the option to expose additional namespaces over AUTH-RPC are at the end.

Prerequisites

  • Docker or Kubernetes with Helm installed
  • Bonder private key
  • Chain information JSON for your Arbitrum chain

Docker deployment guide

Step 1: Set up the validation node

First, generate a JWT secret for secure communication:

xxd -l 32 -ps -c 40 /dev/urandom > /tmp/nitro-val.jwt

Start the validation node with the JWT secret:

docker run --rm -it \
--entrypoint nitro-val \
-p 0.0.0.0:5200:5200 \
offchainlabs/nitro-node:v3.9.9-6b0af88 \
--auth.addr 127.0.0.1 \
--auth.origins 0.0.0.0 \
--auth.jwtsecret /tmp/nitro-val.jwt \
--auth.port 5200
--metrics \
--metrics-server.addr=0.0.0.0 \
--metrics-server.port=6070

The validation node will listen on port 5200, which will also enable the metrics server on port 6070.

Step 2: Set up the bonder node

Copy the JWT secret to your mount directory:

cp /tmp/nitro-val.jwt /some/local/dir/arbitrum

Start the bonder node with the following command, connecting it to your validation node:

docker run --rm -it \
-v /some/local/dir/arbitrum:/home/user/.arbitrum \
offchainlabs/nitro-node:v3.9.9-6b0af88 \
--parent-chain.connection.url=<parent-chain-endpoint> \
--node.staker.enable=true \
--node.staker.strategy=MakeNodes \
--node.staker.parent-chain-wallet.private-key=<staker_private_key> \
--chain.info-json=<Your_chain_info> \
--execution.forwarding-target=<forwarding_target> \
--node.block-validator.validation-server-configs-list="[{\"jwtsecret\":\"/home/user/.arbitrum/nitro-val.jwt\",\"url\":\"ws://Your_validation_address\"}]"

Replace the placeholders with your specific values:

  • <parent-chain-endpoint>: Your parent chain RPC endpoint
  • <staker_private_key>: Your bonder's private key
  • <Your_chain_info>: Chain information JSON
  • <forwarding_target>: Your forwarding node URL (usually is the sequencer endpoint)
  • Your_validation_address: Address of your validation node (including port)

Kubernetes deployment with Helm

Arbitrum provides a community Helm chart for Kubernetes deployment.

Step 1: Create validation node configuration

Create a file named validation_values.yaml:

configmap:
data:
parent-chain:
id: 1 # Use appropriate parent chain ID
connection:
url: 'https://your-parent-chain-rpc'
execution:
forwarding-target: 'https://your-forwarding-node'
node:
staker:
enable: true
strategy: 'MakeNodes'
parent-chain-wallet:
private-key: 'your-staker-private-key'
chain:
name: 'Your Chain Name'
id: 42161 # Your chain ID
info-json: '[Your chain info JSON]'

jwtSecret:
enabled: true
value: 'Your 32 bytes hex jwt'

validator:
enabled: true
splitvalidator:
deployments:
- name: 'current'

Step 2: Deploy the validation node

helm install nitro-validator offchainlabs/nitro --values validation_values.yaml

Monitoring and maintenance

  • Monitor your bonding and validation node logs regularly:

    # For Docker
    docker logs -f <container_id>

    # For Kubernetes
    kubectl logs -f <POD>
  • Check the status of both the bond and the validation node through the Arbitrum dashboard or API

Additional configurations for validation nodes

To get a full list of parameters for the validation node, you can run the following command:

docker run --rm -it --entrypoint nitro-val offchainlabs/nitro-node:v3.9.9-6b0af88 --help

Additional configurations for helm charts

For more advanced helm chart configurations, please refer to the Arbitrum community Helm Chart README

Monitoring

To check if your validation node is running correctly, you can check the rpc_duration_validation_validate_success_count metric in your metrics server.

This metric is a counter of the number of successful validation calls; if it is increasing, it means your validation node is running correctly.

You can also check where this log (validation node started) appears:

  • If this log appears on the validation node, it means your validation node is running correctly.

  • If this log appears on the bond node, it means your bond node is still validating itself. It indicates that your bond node is not connecting to the validation node correctly; you need to double-check your configuration.

Reference: the validation_* API

When AUTH-RPC is enabled, the validation node registers the validation namespace, exposing the following methods (all prefixed validation_ in RPC requests):

MethodPurpose
validation_nameReturns the validation node identifier.
validation_capacityReturns the configured concurrent-execution capacity.
validation_roomReturns the number of currently available execution slots.
validation_validateRuns one validation against a given input and WASM module root.
validation_wasmModuleRootsLists the WASM module roots this node can validate.
validation_stylusArchsLists the Stylus target architectures the node supports.
validation_createExecutionRunStarts a long-running execution and returns an execid handle.
validation_getStepAtReturns the machine hash and global state at a given step.
validation_getMachineHashesWithStepSizeBatch step-hash lookup, used during challenge resolution.
validation_getProofAtReturns the one-step proof at a given step.
validation_prepareRangePre-loads execution state for a step range.
validation_execKeepAliveHeartbeats an execution run to extend its retention.
validation_checkAliveProbes that an execution run is still loaded on the validation node.
validation_closeExecReleases an execution run's resources.

These methods are internal protocol calls between the bond and the validation node. You normally don't invoke them directly—the bonder calls them automatically when it needs validation work. This reference is most useful for reading logs or debugging connectivity between the two components.

Advanced: exposing additional namespaces over AUTH-RPC

--auth.api accepts a list of namespaces, not just validation. You can add others—for example, eth or net — if you want to grant a trusted client read access to those APIs without exposing them on the public RPC:

--auth.api validation,eth,net

Anything listed here is served on the AUTH-RPC endpoint and gated by the JWT, so the caller must hold the same JWT secret to access it. The endpoint still listens only on --auth.addr (default 127.0.0.1), so keep it on loopback or a private network — JWT authentication alone is not a substitute for network isolation.

This is rarely needed for bonders; the main use case is internal services (a custom monitor, an indexer behind your own bastion) that need authenticated read access to the node.

  • If this log appears on the bonder node (validator node), it means your bonder node is still validating itself. It indicates that your bonder node is not connecting to the validation node correctly; you need to double-check your configuration.