Start the node
Time: 5 to 15 minutes. Launch the container and wait for it to sync with the network.
1. Start the node
2. Watch the logs
docker compose logs -f aztec-sequencer
Press Ctrl+C to exit the log view. The node continues running in the background.
Initial sync takes 5 to 30 minutes depending on your L1 endpoint speed and current chain height. You'll see blocks being processed in the logs. Wait until the node catches up to the current proven tip.
3. Check sync progress
In a new terminal, ask the node which L2 block tips it has seen:
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":1}' \
http://localhost:{{AZTEC_PORT}} | jq '.result | {proposed: .proposed.number, proven: .proven.block.number, finalized: .finalized.block.number}'
Expected output looks like:
{
"proposed": 75432,
"proven": 75408,
"finalized": 75392
}
proposedis the latest block the network is producing. As soon as your node is alive and on the right network, this number should increase every few seconds.provenis the latest block with a verified ZK proof submitted to L1. Lags behindproposedby an epoch or so. This is the "fully synced" signal.finalizedis the latest block whose L1 finalization is also confirmed. Lags behindprovenby an Ethereum epoch.
proven and finalized may show null for the first few minutes after startup, before the node has seen a proven epoch. That's normal. Re-run the command after a minute or two; the numbers should appear and start climbing.
4. Check node readiness and identity
node_isReady returns true once the node is ready to accept transactions:
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"node_isReady","params":[],"id":1}' \
http://localhost:{{AZTEC_PORT}} | jq -r '.result'
node_getNodeInfo confirms which network and version you're on. Use it to catch "I started the node against the wrong --network" mistakes early:
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"node_getNodeInfo","params":[],"id":1}' \
http://localhost:{{AZTEC_PORT}} | jq '.result | {nodeVersion, l1ChainId, rollupVersion, rollupAddress: .l1ContractAddresses.rollupAddress}'
Expected output looks like:
{
"nodeVersion": "4.2.0",
"l1ChainId": 1,
"rollupVersion": "...",
"rollupAddress": "0xae2001f7e21d5ecabf6234e9fdd1e76f50f74962"
}
l1ChainId: 1 is Ethereum mainnet, 11155111 is Sepolia. The rollupAddress should match the address in your track's L1 contract addresses table.
Before you continue
proposedis increasing every few seconds (node is alive).provenis non-null and converging onproposed(node is fully synced).node_isReadyreturnstrue.node_getNodeInfoshows the rollup address and L1 chain id you expect.- Logs show no persistent errors.
Something wrong?
- "Error connecting to Ethereum" — Check
ETHEREUM_HOSTSin your.env. Test withcast block-number --rpc-url YOUR_URL. - Node exits immediately — Run
docker compose logs aztec-sequencer(without-f) to see the exit reason. Common causes: invalid keystore path, port conflict, or Docker out of disk space. - Sync stuck — Your L1 endpoints may be rate-limited. Consider self-hosting Geth + Prysm or using a higher-tier provider plan.
- P2P connection issues — Verify port forwarding with
nc -zv YOUR_IP 40400. Check both TCP and UDP are forwarded.
Stuck? Ask in Discord.