This guide gets you a GenLayer node on Testnet Asimov: the software installed, GenVM set up, a systemd service that survives a reboot, and three independent checks that tell you whether the thing is actually working.
Read this paragraph before you rent anything, because it changes what Step 6 actually asks of you. GenLayer's validator testnets — Asimov and Bradbury — are permissioned. Asked directly in the project's Discord, GenLayer team members ras and Rüzgâr said so plainly (2026-09-03): "Did you join the waitlist in the portal? Asimov/Bradbury are still permissioned, so you won't be able to run them until you graduate from the waitlist." Join the waitlist at portal.genlayer.foundation/validators — and do it with a fresh wallet, one that has never held funds with real value, not the wallet you use anywhere else. This is a validator programme judging real applicants, not a testnet faucet, and the same rule that keeps a throwaway key away from anything that matters keeps a wallet you actually use away from a form you do not control.
The two rollup config values in Step 6 are the shape of what admission gets
you, not a separate mystery to solve first. Per the project's own dependencies
section, they identify a ZKSync Full Node connected to the GenLayer chain
— a second piece of infrastructure every validator needs beyond the node this
guide installs, that the operator either runs themselves or borrows access to,
since "one full node can be shared between multiple validators." Nothing in
the published documentation says how to stand one up: no container image, no
genesis block, no L1 settlement endpoint. The v0.5.14 archive ships both
fields as the literal placeholder FILLME, the setup guide's own example
config ships them as TODO: Set your GenLayer Chain ZKSync HTTP RPC URL here,
the upgrade page says those URLs changed without saying what to, and the
project's own setup automation carries the same gap with the comment "get from
GenLayer team or docs". The values arrive when the waitlist admits you, per
the Discord answer above — so this guide takes you as far as the published
sources actually go, tells you exactly what is missing and why, and stops
there rather than guessing a URL and having you paste it into a root shell.
Budget about forty minutes of typing, and from $16 a month for a server. Two costs are not in that figure: validator mode needs a 42,000 GEN stake, and every node needs access to a large language model, which you either pay for or obtain as partner credits.
Hardware requirements
GenLayer publishes hardware figures on two pages, and they do not quite agree. The setup guide says "8-core (AMD64 only)". The system requirements page says "at least 8 cores/16 threads". The second is the more specific claim, so it is the one to plan against — and it matters more than it looks, because every provider in Step 1 sells threads and calls them vCPUs.
| Resource | Published requirement | Why it matters |
|---|---|---|
| CPU | 8 cores / 16 threads | A plan advertising "8 vCPU" is 8 threads, roughly 4 physical cores — half the ask. This is the line that decides which plan you buy. |
| Architecture | AMD64 only | The docs state ARM64 is not supported at this time. The cheap ARM instances that are good value at this size are ruled out entirely. |
| Memory | 16 GB | The docs give the reason: GenVM spawns sub-VMs for contract calls, and each one can take up to about 4 GB. |
| Storage | 128 GB SSD or NVMe | The stated minimum, with NVMe preferred. Chain data grows; treat 128 GB as a floor, not a target. |
| Network | 100 Mbps | The stated minimum. The same page recommends 1 Gbps or better. |
| OS | 64-bit Linux | Ubuntu, Debian or CentOS are the ones named. |
| Software | Docker, Python 3 with pip and venv | Docker runs the WebDriver container GenVM needs for web access. Python builds GenVM. |
| GPU | Not required | Only needed if you choose to run a language model on the same box rather than calling a hosted one. |
Source: system requirements and the validator setup guide, both read 2026-09-01.
Step 1: Choose your hardware
Two honest options. The architecture constraint narrows both.
Path A: rent a VPS
A rented server gives you a static IP, real bandwidth, and a machine that stays online when your laptop closes. It is the fast path, and at this size it is not expensive.
We priced the spec above at the four providers this site has referral
relationships with, on 2026-09-01, reading each provider's own live page or
public API. The full working is in our sourcing note in the repository,
docs/research/genlayer-node-commands-2026-09.md.
| Provider | Cheapest plan at 8 vCPU | Cheapest plan at 16 threads | Term |
|---|---|---|---|
| Contabo | Cloud VPS 8 — 8 vCPU, 24 GB, 300 GB SSD, EUR 14.00/mo incl VAT | Cloud VPS 16 — 16 vCPU, 64 GB, 500 GB SSD, EUR 37.00/mo incl VAT | headline price is the 24-month term |
| Hostinger | KVM 8 — 8 vCPU, 32 GB, 400 GB NVMe, $25.99/mo | nothing larger sold | promo term, renews at $49.99/mo |
| Vultr | 8 vCPU, 16 GB, 350 GB NVMe, $96.00/mo | 16 vCPU, 32 GB, 300 GB, $320.00/mo | no annual term |
| DigitalOcean | Basic — 8 vCPU, 16 GiB, 320 GiB SSD, $96.00/mo | CPU-Optimized 16 vCPU, 32 GiB, $336.00/mo | no annual term |
The honest pick is Contabo, on either reading of the CPU requirement, at roughly a fifth of the cloud price. We earn a commission if you use that link, and we want to be exact about what that did and did not decide: Contabo is the cheapest plan meeting the spec by a margin no commission could close, and it would win this comparison if we earned nothing from it. Vultr and DigitalOcean are providers we also earn from, and they lose this comparison; they are linked above anyway so you can check the rejection yourself.
Three things to know before you click, none of them in our interest to tell you:
- Contabo's EUR 14.00 is a 24-month price, not a monthly one. Their per-product configurator returned an HTTP 500 error from their own servers every time we tried it on 2026-09-01, so we could not read the true one-month figure and are not going to guess it. Check the contract-term selector at checkout before you pay. A testnet phase can end well inside two years, and prepaying a long term for a network that may close is a bad trade at any discount.
- Hostinger's $25.99 renews at $49.99, which its own page states plainly.
- Vultr and DigitalOcean have no annual term at all, and for a temporary testnet that is a genuine advantage rather than an oversight. You pay more per month and you can stop whenever you like. If you expect to run this node for a few weeks to see how the network behaves, that flexibility may be worth more than the difference in price. If you intend to keep a validator running, it will not be.
Provider slot. You are choosing a server with at least 8 real cores on AMD64, 16 GB of memory and fast local storage.
Path B: use hardware you already own
A desktop or home server with 8 cores and 16 GB clears the bar, and it costs you nothing extra. Check the architecture first — an Apple Silicon Mac or a Raspberry Pi will not run this node at all, because the project ships AMD64 builds only and says ARM64 is unsupported.
The tradeoffs are the usual ones and they are real. A home connection drops, and a node that keeps falling out of sync is worse than no node. The machine has to stay powered and wired. Docker has to be able to run without fighting whatever else the machine does.
You do not need to forward any ports for the node to sync and be queryable by you: the RPC listener on port 9151 and the operations port 9153 are for your own use, and this guide binds nothing to the public internet.
Hardware slot. You are choosing the storage to put underneath this — an NVMe drive with room well past the 128 GB minimum.
Step 2: Check the machine can take it
Run these on the machine that will host the node, before downloading anything. The first one is the check that saves you the most time, because a wrong answer here means nothing else in this guide will work.
uname -mx86_64x86_64 is what you want. If you see aarch64 or arm64, stop — the project
publishes no ARM build, and no amount of configuration will fix it.
Now confirm the size of the machine. The first number is threads, not cores:
nprocfree -gdf -h /You are looking for at least 16 from nproc, at least 15 on the total line from
free -g, and at least 128 GB free on the filesystem that will hold the data
directory.
Step 3: Install the prerequisites
The node needs Docker and Python 3. A fresh Ubuntu server has Python but not Docker, so this step installs Docker before anything asks for it.
Start with the Python pieces and the one download tool this guide uses later.
GenVM needs pip and venv, not just the interpreter, and Step 4 fetches the node
tarball with wget, which a minimal server image does not always carry:
sudo apt updatesudo apt install -y python3 python3-pip python3-venv wgetNow Docker. GenLayer's own install automation pipes a remote script straight
into a root shell, and that works — it is also a habit worth not building, and
it gives you no say in what lands on the machine. The commands below are
Docker's documented apt-repository method, read from
Docker's install page on
2026-09-02. They add Docker's signing key and repository, so apt keeps Docker
up to date afterwards like anything else.
First the key and the repository:
sudo apt install -y ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.ascsudo tee /etc/apt/sources.list.d/docker.sources <<EOFTypes: debURIs: https://download.docker.com/linux/ubuntuSuites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")Components: stableArchitectures: $(dpkg --print-architecture)Signed-By: /etc/apt/keyrings/docker.ascEOFsudo apt updateThe two $( ) substitutions work out your Ubuntu release name and your CPU
architecture, so the same paste is correct on 24.04 and on 26.04. If the last
line reports that it cannot find the repository, the release you are on is one
Docker does not publish for — check the supported list on the page linked above
before going further.
Then the packages themselves:
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginOn a fresh Ubuntu server those packages start the Docker daemon for you and set
it to start at boot. Confirm it with sudo systemctl status docker --no-pager,
and start it with sudo systemctl start docker if it is not running.
Now check all three, which is also how you confirm the install worked:
docker --versiondocker compose versionpython3 --versionDocker Engine 20.10 or newer and the Compose plugin are what the project asks
for. If docker compose version reports "is not a docker command", you have the
old standalone docker-compose binary rather than the plugin, and the install
above is what replaces it.
Step 4: Download and unpack the node software
There is no public GitHub repository for the node — we checked, and the releases API returns 404. The builds live in a Google Cloud Storage bucket, which is what the docs point at.
curl -s "https://storage.googleapis.com/storage/v1/b/gh-af/o?prefix=genlayer-node/bin/amd64" | grep -o '"name": *"[^"]*"' | sed -n 's/.*\/\(v[^/]*\)\/.*/\1/p' | grep -v rc | sort -Vru | head -n 5v0.5.14
v0.5.13
v0.5.12
v0.5.11
v0.5.10If the top line is newer than v0.5.14, use that version everywhere below instead.
Create the install root. This guide uses /opt/genlayer-node with a versioned
subdirectory, because that is the layout the project's own monitoring and
automation assume, and because it makes the upgrade in Maintenance a directory
switch rather than an overwrite:
sudo mkdir -p /opt/genlayer-nodesudo chown $(id -un) /opt/genlayer-nodemkdir -p /opt/genlayer-node/v0.5.14Download the build:
cd /opt/genlayer-nodewget https://storage.googleapis.com/gh-af/genlayer-node/bin/amd64/v0.5.14/genlayer-node-linux-amd64-v0.5.14.tar.gzcd /opt/genlayer-nodetar -xzf genlayer-node-linux-amd64-v0.5.14.tar.gz --strip-components=1 -C ./v0.5.14ls v0.5.14/bingenlayernodeIf that prints genlayernode, the layout is right and every path below will
resolve. If it errors with no such file or directory, the archive went in with
its wrapper directory intact — remove v0.5.14 and run the block again with
--strip-components=1 in place.
Point stable symlinks at the version you just unpacked. Everything later in this guide, including the systemd unit, refers to these rather than to a version number:
mkdir -p /opt/genlayer-node/v0.5.14/data/nodemkdir -p /opt/genlayer-node/v0.5.14/configs/nodeln -sfn /opt/genlayer-node/v0.5.14/bin /opt/genlayer-node/binln -sfn /opt/genlayer-node/v0.5.14/configs /opt/genlayer-node/configsln -sfn /opt/genlayer-node/v0.5.14/data /opt/genlayer-node/dataStep 5: Set up GenVM
GenVM is the component that executes intelligent contracts, and it ships as a separate set of binaries the setup script fetches and verifies. This takes a couple of minutes and needs network access:
python3 /opt/genlayer-node/v0.5.14/third_party/genvm/bin/setup.pyThe script downloads any missing runners, verifies their hashes, sets the
interpreter on the binaries, and precompiles the built-in runners. If it fails
on a missing Python module, go back to Step 3 — python3-venv is the piece
people usually lack.
Step 6: Write the configuration
Use the config the tarball ships rather than one you found somewhere. The schema changes between releases, and the upgrade notes are explicit that copying an old config forward is how nodes fail to start.
The archive already contains configs/node/config.yaml, filled in except for the
values only you can supply — there is no separate .example file to copy, whatever
a guide that has not unpacked the archive may tell you. Keep an untouched copy
first, so you can see exactly what you changed:
ls /opt/genlayer-node/v0.5.14/configs/node/cp /opt/genlayer-node/v0.5.14/configs/node/config.yaml /opt/genlayer-node/v0.5.14/configs/node/config.yaml.origconfig.yamlNow three blocks to look at, and in v0.5.14 only the third of them is actually work. Confirm the first two rather than retyping them — we unpacked the real archive on 2026-09-02 and both already carry the values below. If yours differ, the file is from another release and these are what it should say.
First, the consensus block, which is what selects Testnet Asimov rather than the other deployment on the same chain:
consensus:consensusaddress: "0xe66B434bc83805f380509642429eC8e43AE9874a"genesis: 17326Second, the node block. The shipped file already leaves the two addresses empty, which is what you want if you are not staking — a node with no validator wallet configured runs as a full node instead:
node:mode: "validator"validatorWalletAddress: ""operatorAddress: ""Third, the rollup block. This is the one that is genuinely yours to fill in, and the one you cannot fill in from the documentation.
rollup:genlayerchainrpcurl: "PUT THE HTTPS URL YOU WERE GIVEN HERE"genlayerchainwebsocketurl: "PUT THE WSS URL YOU WERE GIVEN HERE"provider: "the rollup operator name you were given"You also need an API key for a language model, set as an environment variable before the node starts. The project lists partner providers offering free credits to validators — Heurist, Comput3, io.net, Chutes and Morpheus are the ones named on its GenVM configuration page, along with the variable name each one expects. Any OpenAI-compatible provider works; the same page documents how to add one.
Step 7: Create the operator key and start the node
The operator key is the hot key your node signs with. If you are staking, the staking wizard exports one for you to copy across. If you are not, generate one here:
cd /opt/genlayer-node/v0.5.14./bin/genlayernode account new -c /opt/genlayer-node/v0.5.14/configs/node/config.yaml --setup --password "choose a password of at least eight characters"Back that key up before you go any further. Losing it means the owner has to assign a new operator, which is recoverable but tedious; the docs are blunt about backing it up and they are right.
The operator key is a hot signing key for this node, not a place to hold funds — Testnet Asimov's tokens carry no real value, so there is nothing at stake in it yet. A hardware wallet is worth the cost once you are holding or signing for something that does:
Hardware wallet
Ledger keeps a private key on a physical device, off the machine running your node, and asks for a button press before it signs anything. That is worth having once the key or address in question holds funds with real value. It is not required for anything on this site: every guide here runs on a testnet, testnet tokens carry no real value, and a fresh software wallet -- a new browser-extension or app wallet, ideally in its own browser profile and separate from anything holding real funds -- is enough for that. See Wallets and exchanges for node runners for the difference and where hardware wallets actually fit.
Start the WebDriver container GenVM uses for web access:
cd /opt/genlayer-node/v0.5.14docker compose up -dCheck the configuration before starting anything. This is the command that tells you whether Step 6 is complete:
cd /opt/genlayer-node/v0.5.14./bin/genlayernode doctorThe doctor command validates the consensus contract, GenVM module
connectivity, the language-model provider, and zkSync accessibility. If you
did not get the rollup URLs, the zkSync check is the one that fails, and that is
the expected result — not a mistake you made. Everything before it should
pass.
Run the node under systemd so it survives a reboot and a dropped SSH session.
Save this as /etc/systemd/system/genlayer-node.service, substituting your
password:
[Unit]Description=GenLayer NodeAfter=network.target docker.serviceRequires=docker.service[Service]Type=simpleUser=rootWorkingDirectory=/opt/genlayer-nodeExecStart=/opt/genlayer-node/bin/genlayernode run --password YOUR_NODE_PASSWORDRestart=alwaysRestartSec=10[Install]WantedBy=multi-user.targetThen enable and start it:
sudo systemctl daemon-reloadsudo systemctl enable genlayer-nodesudo systemctl start genlayer-nodeVerify your node
"The command ran" and "the node works" are different claims. Here are three checks that answer different questions, and what a bad answer to each one means.
1. The service is up, and stays up. Run this, wait a minute, run it again:
systemctl is-active genlayer-nodeactiveAnything other than active means it never started. If it says activating the
first time and active the second, that is fine. If it alternates between
active and activating it is restart-looping, which the Restart=always line
will hide from you unless you look — check the logs before assuming it is
healthy.
2. The node reports itself healthy, including its GenVM modules. The operations port answers a plain HTTP request:
curl -s http://localhost:9153/healthThe response carries an overall status of up or down, the node and
protocol versions, and a genvm_modules object with an entry for llm and one
for web. Each is healthy, suspect, degraded or unknown. A module
sitting at unknown has not been exercised yet; one at degraded means your
language-model provider or the WebDriver container is not answering, and
contracts will fail even though the node looks alive.
3. It is caught up. Ask GenVM how far behind the chain tip it is:
curl -s -X POST http://localhost:9151 -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"gen_syncing","params":[]}'You want blocksBehind falling toward zero. A number that stays flat means the
node is not making progress, not that it is nearly done.
If you want to see what a healthy answer looks like before your own node gets there, ask the public Asimov endpoint the same question. This is the real response we got on 2026-09-01; your block numbers will be larger:
curl -s -X POST https://rpc-asimov.genlayer.com -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"gen_syncing","params":[]}'{"jsonrpc":"2.0","result":{"syncedBlock":"0x135c577","latestBlock":"0x135c577","blocksBehind":0},"id":1}Common errors
The failures a beginner actually hits here, with the literal text each one produces.
command not found: genlayer-node-linux-amd64-v0.5.14.tar.gz — you pasted
the extract command from the project's setup guide, which wraps its arguments in
backticks. Use the form in Step 4 instead. Nothing is broken; the archive is
still sitting there.
cannot execute binary file: Exec format error — the machine is not AMD64.
Run uname -m; if it answers aarch64, the project publishes no build that
will run there. This is the one problem in this guide with no workaround.
module_failed_to_start — GenVM could not start a module. The usual cause
is that no language-model provider is enabled, or the API key environment
variable is not set where the node can see it. Check the provider block in
third_party/genvm/config/genvm-module-llm.yaml and confirm the key is present
in the node's environment, not just in your shell.
NO_PROVIDER_FOR_PROMPT — the node is running and a contract asked for
something none of your enabled models can do. At least one backend needs
supports_json: true, and if a contract sends images you need one with
supports_image: true as well. A validator with only a text model will fail
image prompts and lose consensus on them.
The doctor zkSync check fails — expected, until you are off the GenLayer
waitlist. Asimov and Bradbury are permissioned testnets (GenLayer Discord, ras
and Rüzgâr, 2026-09-03); the rollup values in Step 6 arrive with admission at
portal.genlayer.foundation/validators,
not from anything you can configure or look up yourself. Once you have them,
they identify a ZKSync Full Node connected to the GenLayer chain — a second
piece of infrastructure the project's own docs require and do not explain how
to run. Every other check should pass; if one of those fails too, fix it before
chasing this one.
node is not synced in the logs, persistently — after a breaking upgrade
this is normal for a while, and the fix is patience plus a correct genesis
value in the consensus block. Without it the node scans from block zero, which
takes far longer than it needs to.
Maintenance
Weekly, and it is a short list.
Check the service is still up and the node still healthy — the two commands from the Verify section are the whole routine. Then look at the logs; the bounded form is what you want, because the following form runs until you stop it:
sudo journalctl -u genlayer-node -n 50 --no-pagerWatch disk. 128 GB is the documented floor, not a comfortable steady state, and
chain data only grows. Running df -h / is enough.
Upgrades are a directory switch, not an overwrite. The project's own procedure is to unpack the new version into a fresh folder, configure it from the new example rather than copying the old config forward, copy the data directory across, run the doctor check, then stop the old node and start the new one. The symlink layout in Step 4 exists to make that last part a one-line change. Read the changelog first: some releases are breaking, and a breaking release means a new consensus deployment, a wiped database, and re-staking if you are a validator.
Back up the keystore before any upgrade, breaking or not. It lives in
data/node/keystore/. There is a documented step for deleting the database
during a breaking upgrade; it is deliberately not printed here as a runnable
command, because two of the project's own pages disagree about where the install
root is, and a delete aimed at the wrong directory is not recoverable.
FAQ
Do I get rewarded for running this? Nothing is promised here, because nothing is promised in the sources we can read. The project's monitoring page says forwarding your node's metrics to the Foundation dashboard may positively influence testnet points or rewards, and that visible healthy nodes are prioritised — that is the project's own wording, hedged the way they hedged it, and it is linked in the sidebar. The launch material about an incentivised testnet lives on a host that blocks us entirely, so we have not read it and will not repeat it second-hand. If that changes, the claim goes in this guide with the project's own URL beside it, and not before.
Do I need 42,000 GEN to follow this guide? No. The stake is what makes a node a validator — one that votes in consensus and earns the validator fee. Everything in this guide works without it, and a node with no validator wallet configured runs as a full node instead. Be aware that the full-node mode is barely documented: the shipped configuration file offers the setting and the setup guide mentions it once, in passing, with no dedicated page. We are describing an option the project ships, not a supported path it has written up.
How do I actually get the rollup values in Step 6? Join the waitlist. Asimov and Bradbury are permissioned validator testnets — asked directly, GenLayer team members ras and Rüzgâr said so in the project's Discord (2026-09-03): "Did you join the waitlist in the portal? Asimov/Bradbury are still permissioned, so you won't be able to run them until you graduate from the waitlist." Join at portal.genlayer.foundation/validators with a fresh wallet — never one holding funds — and the values arrive with admission, not from anything published or askable in advance.
Why can I not just use the public RPC for the rollup URL? Because it is the wrong kind of thing, and because we tried it anyway and it does not work. The rollup fields want a ZKSync Full Node connected to the GenLayer chain — infrastructure a validator runs or borrows once admitted off the waitlist, per the project's own dependencies section — not a public API endpoint. The public RPC answers Ethereum methods but rejects the zkSync methods the node needs, with "Method not found". It is the obvious guess and it is wrong, which is exactly why it is worth stating rather than leaving you to find out.
Which testnet am I on?
Whichever one your consensus.consensusaddress selects. Both published testnets
report chain ID 4221 and share a genesis hash, so nothing you can query about
the chain will distinguish them. Asimov Phase 5 is the address in Step 6.
Will a cheap ARM instance work?
No. The docs say ARM64 is not supported and the project ships AMD64 builds only.
Check with uname -m before you pay for anything.
Why is this guide marked pending? Because nobody has run these commands end to end and captured the output. That badge is cleared by a verification harness, never by an author who thinks the commands look right. Every command here is traced to a first-party source in our research note, and four of them are corrections to commands the project's own documentation publishes in a broken form — but traced is not the same as tested.