Run a node
Start it
mina node --network devnetThe node finds peers, syncs, then follows the tip of the chain. Watch it in the dashboard at http://127.0.0.1:3000. Stop it with Ctrl-C.
The node runs in the foreground: it stops when you close the terminal or log out. To keep it running, and start it again after a reboot, run it in the background as a service.
On a server, open the dashboard through an SSH tunnel. mina node status reports the node's state from another shell.
The CLI reference lists every option of mina node.
mina node statusThe work directory
The node keeps its data in ~/.mina. Use -d DIR, or set MINA_HOME, for another directory.
- <chain id>/frontier/
- The saved chain state
- ledger-accounts/
- The accounts of the staking, next epoch and root ledgers
- mina.log, mina.log.1, ...
- The logs
- p2p-secret-key
- The node's peer identity, made at the first start
- proof-cache/
- The SNARK pool's cached proofs
- snark-worker.json
- The worker setting chosen in the dashboard
- snark-worker-included.json
- The worker's work that blocks included
- vrf-evaluation/
- A block producer's saved slot checks
- block-production.json
- A block producer's won slots and what became of them
- crashes/
- A report of each crash
- last-start.json
- How the node was started, for bug reports
- bug-reports/
- Reports mina report saved
The verifier index cache, built at the first start, is in ~/.mina/circuit-blobs/ whatever the work directory.
Ports
Default ports
- 3000 (--port)
- HTTP: the API and dashboard.
- 8302 (--libp2p-port)
- Peers. Open it to let peers reach your node.
The HTTP port listens on 127.0.0.1 only by default. --http-addr (or MINA_HTTP_ADDR) sets another listening address, such as a private interface, and --http-addr 0.0.0.0 listens on all IPv4 interfaces. Before changing it, read viewing it on a server. The peer port is separate and may be open to other nodes.
Saved state and restarts
The node saves the chain state as it goes, and a restart picks up from it instead of syncing from the start. The first save comes a few seconds after the node first syncs, then one every 30 minutes; the log says checkpoint written each time. A node stopped before its first save syncs from the start again. It checks the saved state first: if the state is too old or fails a check, the node syncs afresh and says why in its log. If restoring it crashes the node three times, the node deletes it. A stop during a restore (Ctrl-C, systemctl stop, docker stop) doesn't count.
--no-frontier-store turns saving off.
Proof cache
The SNARK pool caches proofs on disk in proof-cache/ under the work directory. Disk use varies with the pool. Files are freed when their last reference is dropped; a restart clears old cache files. Do not share a work directory between running nodes.
--no-proof-cache keeps those proofs in memory instead. A block producer keeps them in memory unless started with --proof-cache. To inspect cache files, bytes and errors:
curl -s http://127.0.0.1:3000/stats/memory/proofsRun in the background
With systemd, a user service keeps the node running after you log out and starts it again after a reboot. It runs the binary from the install page with the same work directory (~/.mina) and dashboard port (3000) as the foreground command, so it keeps any chain you have already synced. Stop a node running in a terminal first, with Ctrl-C.
Create its directory with mkdir -p ~/.config/systemd/user, then save this as ~/.config/systemd/user/minanode.service. The name keeps it apart from the OCaml package's mina.service.
[Unit]
Description=Mina devnet node
[Service]
ExecStart=%h/.local/bin/mina node --network devnet \
--disable-filesystem-logging
Restart=on-failure
[Install]
WantedBy=default.target--disable-filesystem-logging leaves the logs to the journal instead of mina.log. Everything else is the foreground default.
systemctl --user daemon-reload
systemctl --user enable --now minanode.service
loginctl enable-linger "$USER"
journalctl --user -u minanode.service -fLinger keeps your user service manager running after logout and starts it at boot. If enabling linger is refused, ask the server administrator to enable it for your account.
The dashboard stays at http://127.0.0.1:3000; on a server, use the SSH tunnel. Stop the service with systemctl --user stop minanode.service. For a bug report, take the log from the journal:
mina node status
journalctl --user -u minanode.service | mina report --log -Troubleshooting
Sync seems stuck
Connecting means no peer has connected. Listening means peers have connected but have not sent a tip. Bootstrap fetches ledgers and blocks. Catchup applies blocks to reach the tip. Synced means the node has caught up. Starting means it has not reported a phase yet.
Warnings such as Ledger unavailable or TransactionPoolFetchAccountsFailed before the first Synced are normal: the transaction pool asks for accounts before the ledger is ready. If they keep coming after Synced, collect a report. A first start also logs no ledger to copy for sync, starting from an empty one and a stray [-] no FUZZER conf specified line. Kad warnings such as Skipping updates to Kad entry multiaddress list can repeat at any time, and a producer key with no stake logs Empty delegator table. All of these are harmless.
Check the peer count, target height and log progress before restarting. Ledger downloads take time, and a quiet network may leave the tip unchanged. If peers advance but your node makes no progress, or it repeats errors, collect a report before deleting data. Replace the directory and URL below if you changed them.
mina node status --node http://127.0.0.1:3000
mina report -d ~/.mina --node http://127.0.0.1:3000 \
-m "Sync stopped progressing" --output report.mdReview the report, then follow reporting a bug.
The dashboard will not open on a server
HTTP listens on 127.0.0.1 by default. Use an SSH tunnel to the node's HTTP port.
Port already in use
The node stops startup if its operator HTTP or signaling listener cannot bind, and the error names the flag and port. An enabled --webrtc-signal-port must use a different port when its listening address overlaps --http-addr. A wildcard address such as 0.0.0.0 also overlaps 127.0.0.1.
Choose an unused HTTP port with --port and an unused peer port with --libp2p-port. Update the dashboard URL, tunnel and status command to match. For a second node, also use a separate work directory. Do not stop another service to free its port.
mina node --network devnet -d ~/.mina-second \
--port 3010 --libp2p-port 8312Command not found, or another mina
Try the installed binary by its full path. Add its directory to PATH in this shell, and in your shell startup file for later shells.
If mina --version prints anything but this release's mina line, another program called mina, such as the OCaml node, comes first on PATH. command -v mina shows which one runs. Put ~/.local/bin first, as below, or use the full path.
~/.local/bin/mina --version
export PATH="$HOME/.local/bin:$PATH"
command -v mina
mina --versionLogs
The node logs to the terminal and to mina.log in its work directory. The log rotates at 20 MiB and 10 files are kept, so logs take at most 200 MiB.
--log-level debug logs more detail. The user service logs to the journal (see run in the background).
GraphQL
The node answers GraphQL queries at /graphql on its HTTP port, for wallets, explorers and scripts. The dashboard's GraphQL page shows the address and an example to copy.
curl -s http://127.0.0.1:3000/graphql \
-H 'content-type: application/json' \
-d '{"query": "{ syncStatus bestChain(maxLength: 1) { stateHash } }"}'Sending transactions (sendPayment, sendDelegation, sendZkapp) is off unless you start the node with --enable-tx-submission. Turn it on only for a node whose HTTP port only you can reach.
A request may carry up to 1.25 MiB of body and of query text, and up to 24,576 tokens. That admits the largest zkApp command Mesa accepts (15 proofs) as o1js builds it, inline in the mutation. A valid command padded with many empty events can still exceed the limits. The node admits bodies over 256 KiB one at a time. Another large body waits up to 30 s, then gets HTTP 503.
--public-graphql keeps the earlier limits (256 KiB of body, 64 KiB of query text and 8,192 tokens) and refuses mutations.
HTTP API
GET /status answers with the node's sync state, best tip and peers as JSON, and GET /build_env with its build. The dashboard's Status page shows both, and mina node status sums them up.
Light clients read the best tip and account Merkle paths from /light/*: see light client endpoints.