Troubleshooting
This page helps operators find the cause of a ciphernode problem from what they see. Each section starts with the symptom, explains what it means, and gives the checks in order. At the end of a section, you know if the node needs an action from you or if it recovers without one.
Symptoms
| Symptom | Section |
|---|---|
This node was NOT selected for sortition for each E3 | Not selected for committees |
Failed to submit ticket: … | Ticket submission fails |
DHT put record failed: the quorum failed; needed 1 peers | DHT put record fails |
No connected peers, or Rejected an incompatible Interfold peer | No connected peers |
| E3 requests appear on-chain, but the node logs nothing | The node does not follow the chain |
| The node exits at startup with an error | Startup fails |
| The operating system kills the node or the prover during a DKG | Out of memory |
Read the logs
The CLI sets the log level with flags. See Global options.
| Flag | Level | Use |
|---|---|---|
| None | WARN | Warnings and errors only |
-v | INFO | Normal operation. Most log lines on this page need this level. |
-vv | DEBUG | Detailed diagnosis of one problem |
-vvv | TRACE | Very large output. Use it only for a short time. |
-q, --quiet | ERROR | Errors only |
By default the node logs libp2p gossipsub only at ERROR, because its routine warnings can fill
gigabytes during one E3. RUST_LOG directives apply on top of the flag level and change only the
targets they name. For example, this also shows gossipsub warnings:
RUST_LOG=libp2p_gossipsub=warn interfold start -vThe node writes readable log lines to standard output. Your supervisor collects them, for example
the terminal, journalctl, or docker logs. The Docker image starts the node with -v.
The node also writes each log entry as JSON to ciphernode.jsonl in the node data directory, the
directory that contains db. The file rotates at 25 MiB and keeps four old files,
ciphernode.jsonl.1 to ciphernode.jsonl.4. The Logs view of the
local dashboard shows the same entries.
interfold config get log_file returns the base path of the event log, not a text log. The event
log files (log.0 and one for each chain) are binary. The data directory is the parent directory
of the path that interfold config get db_file returns.
Not selected for committees
Symptom: the node logs This node was NOT selected for sortition for each E3.
This line means that the node has no ticket to submit for the E3. The node is not eligible, all its tickets are in use, or its bond owner is not ranked high enough. The last cause is normal: the committee has a fixed number of seats.
Check the on-chain status
Run interfold ciphernode status --operator 0xOPERATOR.
| Field | Expected value | If not |
|---|---|---|
Registered | true | Register the operator. See Registration. |
Active | true | Continue with the next rows. |
Exit pending | false | A deregistration is in progress. The operator cannot enter committees. |
Ticket balance | The available count is at least minTickets | Buy tickets. |
Ciphernode bond | At least 80 % of ciphernodeBond (the default) | Bond more FOLD. |
Check the causes that the status does not show
If Active is false but the balances are correct, check these causes:
- The release of the node does not meet the on-chain release policy. See Upgrades.
- Governance changed a parameter, and the operator status needs a refresh. See After a governance change.
- A slashing manager banned the operator. Call
isBanned(operator)onSlashingManager.
Read the sortition log lines
Look for these INFO lines before This node was NOT selected for sortition:
Node is not active: the operator was not active atrequestBlock - 1.Node has no tickets in the request-time sortition view: the snapshot balance gave 0 tickets.
Tickets that you add after a request count only for later requests.
Check the local capacity
The node takes part in one E3 for each ticket at the same time. If all tickets are in use by active E3s, the node does not submit. Add tickets to serve more E3s in parallel.
Node not in finalized committee is a different case. The node submitted a ticket, but the best
tickets of other bond owners took the seats. This result is normal.
Ticket submission fails
Symptom: the node logs This node was SELECTED for sortition, and then
Failed to submit ticket: … at the ERROR level.
The message includes the decoded contract error.
| Error in the message | Cause | Action |
|---|---|---|
CommitteeDeadlineReached | The transaction arrived after the committee deadline. | Use a faster RPC endpoint. The window is sortitionSubmissionWindow after the VRF response. |
NodeNotEligible | The operator was not active, or had no tickets at the snapshot. | Check the status as in Not selected for committees. |
InvalidTicketNumber | The ticket number is not in the snapshot range. | Check that the node syncs from a correct RPC endpoint. |
At deployment, sortitionSubmissionWindow was 600 s on mainnet and 180 s on Sepolia. The operator
wallet must have ETH for gas. A slow or rate-limited RPC endpoint delays the transaction. See
RPC endpoints.
When the ticket is already on-chain, the node logs
Ticket already recorded on chain; skipping submission. No action is necessary.
DHT put record fails
Symptom: the node logs these lines during a DKG:
ERROR DHT put record failed: the quorum failed; needed 1 peers
ERROR Operation failed after 2 attempts: DHT put record failed: PutRecordError(QuorumFailed { key: …, success: [], quorum: 1 })Before the second line, the node also logs Attempt 1/2 failed, retrying in 1000ms: … at the WARN
level.
What the error means
During a DKG, the node publishes each DKG document that it makes: its threshold shares, its
encryption key, and its decryption key share. It stores the document in its own DHT store and
gossips a notification to the committee. Separately, it uploads the document to the Kademlia peers
closest to the document's key. The upload uses Quorum::One, so at least one remote peer must
acknowledge it. These errors come from the upload; a failing upload does not hold back the
notification.
An inbound DHT put cannot replace the node's own published record. For a stored replica, the node keeps the later expiry. A record without an expiry keeps its unlimited lifetime.
- The retry sequence. Each upload makes 2 attempts, 1 s apart.
success: []. Remote peers receive records with record filtering on (StoreInserts::FilterBoth). With this setting, a remote peer sends a response even when its filter rejects the record. An emptysuccesslist therefore means that no peer acknowledged the request at all.QuorumFailed, notTimeout. The Kademlia query timeout is 60 s. AQuorumFailedresult before the timeout means that the query had no reachable peers to send the record to.
The node therefore had no admitted and reachable Kademlia peers at that time.
What happens next
The node keeps announcing the document from its own store: again 30 s after the first notification,
then with the wait doubling up to 5 minutes. It retries a failed upload 15 s later, also doubling
the wait up to 5 minutes, and uploads each document again every 30 minutes. It continues until the
document expires or the DKG ends. The DKG ends when the chain reports the E3 stage KeyPublished,
CiphertextReady, Complete, or Failed. The node then ends a put that is uploading its record.
Kademlia reports that end as a quorum failure, and the node logs it at the DEBUG level as
DHT put record cancelled, not as this error. A put that still looks up its closest peers runs on,
and requests already handed to a connection still go out, so such a put can still log this error.
- While the uploads fail, a peer whose DHT lookup reaches this node fetches the document from it. A lookup asks the about 20 peers closest to the key, so in a larger network some peers can fetch the document only after an upload succeeds.
- If the connectivity comes back in time, an upload succeeds and the node recovers without action.
- If the connectivity does not come back in time, the peers that cannot reach this node do not receive its documents for that E3.
Causes
- No connectivity. A firewall or NAT blocks the QUIC port, or the configured peers are down.
After 3 failed dials in a row, the node logs
Evicting unreachable peer <peer> after 3 consecutive failures. The node then keeps that peer out of its Kademlia routing table for 30 minutes. - A network identity mismatch. The Identify protocol string is
interfold/<network_id>/protocol/<protocol_version>/deployments/<hash>/1. The hash is a SHA-256 over the chain ID and the Interfold contract address of every enabled chain. A differentprotocol_version, one more enabled chain, or a differentinterfoldaddress changes the string. Every peer then rejects the node, and the node logsRejected an incompatible Interfold peerwith the reason. - Short churn. Peers restarted at the same time. The errors stop after the peers reconnect.
Checks
Check the release
Run interfold --version.
The release must have the same protocol_version as the network. See
Recent releases.
Check if the errors repeat
Look at the times of the Operation failed after 2 attempts lines.
If the lines repeat for each round, the node is isolated. If they stopped, the problem was short.
Search the log for the peer lines
Search the log for these lines. Most are INFO lines, so the node must run with -v:
| Log line | Level | Meaning |
|---|---|---|
Found <n> peer(s) to dial: | INFO | The peers from the configuration and the network profile. |
Peer admitted | INFO | A peer passed the Identify check. |
Rejected an incompatible Interfold peer | INFO | The Identify check failed. The reason field gives the cause. |
Evicting unreachable peer <peer> after 3 consecutive failures | INFO | Three dials to the peer failed in a row. |
Incoming connection error: … | WARN | An inbound connection failed. |
Peer did not complete Identify before the admission deadline | DEBUG | A connected peer did not send Identify in time. Needs -vv. |
The Starting the scoped Interfold P2P network line shows the identify string of the node.
Compare it with the string of a node that works.
Read the peer state from the dashboard API
If dashboard_port is set, run this command on the host of the node:
curl -s http://127.0.0.1:<port>/api/snapshot | jq '.network'An empty connected_peers list confirms that the node has no admitted peers. last_error shows the
latest network error. Dashboard API describes each field.
Check the chain configuration
Run interfold config check.
The command compares each configured address with the published deployment manifest and reports
STALE lines. Make sure that only the chains that you use are enabled, because each enabled chain
changes the Identify string. A chain entry with enabled: false does not count.
Check the QUIC port
Run interfold config get quic_port. The default is 9091.
Make sure that the firewall, the cloud security group, and the NAT allow inbound UDP on this port.
No connected peers
Symptom: the Overview of the local dashboard shows 0 connected peers, or the log shows peer errors.
The node uses QUIC over UDP. The node admits a peer only after the Identify check passes. The check compares the network identity and the supported Kademlia and sync protocols.
Identify does not cache peer addresses. The node keeps admitted peer addresses in Kademlia and filters loopback addresses when it has a listener on a non-loopback interface. Each compatible Identify exchange refreshes these addresses, so a connected peer can advertise a new address for later reconnection. The node keeps unique filtered addresses within both limits: 8 addresses per peer and 2 KiB of encoded addresses, including peer IDs. Advertised live endpoints take slots first. The remaining slots fill in advertised order. Each update removes superseded Identify addresses. Live connection endpoints remain until they close. A withdrawn endpoint is removed after its last connection closes.
| Log line | Cause | Action |
|---|---|---|
Found 0 peers to dial | The configuration and the network profile give no peers. | Set node.peers, or check node.network. |
Rejected an incompatible Interfold peer with peer network identity '…' does not match '…' | A different protocol version or a different set of enabled deployments. | Compare the release and the enabled chains with the peer. |
Rejected an incompatible Interfold peer with peer does not support … | The peer runs an incompatible release. | Compare the releases. |
Evicting unreachable peer <peer> after 3 consecutive failures | The peer does not answer at its address. | Check the address and that the peer runs. |
Rejected a configured peer whose pinned identity changed | The peer ID in the configured multiaddr is not the ID at that address. | Update the /p2p/<peer-id> part of the multiaddr. |
Some bootstrap peers are unavailable; background retries will continue | A bootstrap peer did not answer. | The node retries every 60 s. Check the address if the warning continues. |
Disconnected a peer that did not establish the gossip subscription | A peer connected but did not subscribe to the protocol gossip topic in 30 s. | The node disconnects the peer and dials it again only after redial_after_seconds: 30 s, doubling up to 30 minutes, plus up to 10%. A subscription ends the wait. Compare the releases if the warning continues. |
The dashboard API shows configured_peers, connected_peers, and gossip_subscribed_peers. A peer
that is connected but not subscribed to the gossip topic cannot take part in committee work. For the
full check sequence, follow the DHT checks.
The node does not follow the chain
Symptom: E3 requests appear on-chain, but the node logs nothing about them.
Check the live subscription
Search the log for Live event subscription active. The node logs this line for each chain.
The node reads live events with a log subscription, so rpc_url must be a ws:// or wss:// URL.
Check the contract addresses
Run interfold config check.
A STALE line means that the configuration has an address that the published deployment does not
use. Update the configuration.
Check the RPC endpoint
Make sure that the endpoint returns recent blocks, serves the full log history, and does not rate-limit the node.
See RPC endpoints.
Startup fails
| Message | Cause | Action |
|---|---|---|
Configuration file not found. Run `interfold ciphernode setup` to create a configuration. | The CLI did not find interfold.config.yaml. | Run the command from the node directory, or use --config. |
another interfold instance is already running for node '<node>' against this data directory … | A second process uses the same data directory. | Stop the other process first. |
ciphernode protocol version <x> does not match required version <y> | The release is for a different protocol version. | Install the release that the chain requires. See Upgrades. |
ciphernode generation <x> is below required generation <y> | Governance requires a newer node release. | Install the new release. |
On-disk schema version <v> is older than this binary's supported version … | The release raised the storage schema. | Reset node state. |
On-disk state has no schema marker … | The event log exists without the matching key/value store. | Restore the stopped backup, or reset the state. |
chain '<name>' has Interfold enabled but no data_availability reader; … | The chain entry has no data_availability block. A configuration from an earlier interfold ciphernode setup does not have it. | Add the block. See Data availability. |
failed to read Interfold release dependencies | The Interfold contract has no nodeReleaseRegistry(). On 25 September 2026, the Sepolia deployment is an example. | Use a chain whose deployment includes the node release gate. |
restored request contexts for E3s … belong to chain <id>, which the configuration does not have … | The data folder has unfinished E3s of a chain that is not in the configuration, for example after a network change. | Add the chain, or keep its entry with enabled: false and its chain_id. Or reset node state. |
restored E3 <id> is not in the Interfold contract … | The RPC endpoint is behind the chain, or the data folder is from another deployment. | Check that the endpoint is synced and the interfold address is right. Reset node state only for another deployment. |
ciphernode startup did not complete within … | The startup sync took longer than node.startup_timeout_secs. | Use a faster RPC endpoint, or increase node.startup_timeout_secs (default 1800). |
Out of memory
Symptom: the operating system kills the node or its prover processes during a DKG. The kernel log shows an out-of-memory kill.
DKG proofs use much memory. multithread_concurrent_jobs sets the number of proof and TrBFV jobs
that run at the same time. The default is 2, and the node can use fewer jobs when the host or
container memory is small. multithread_reserve_threads (default 2) keeps CPU threads free for the
network and the RPC connection. At startup, the node logs the values in a line that starts with
Ciphernode multithread:.
To reduce the peak memory, set a lower multithread_concurrent_jobs under node, or add memory.
See Compute and startup limits and
Requirements.
Still stuck
- Read Tickets and sortition for the selection parameters.
- Ask in the Interfold technical chat (opens in a new tab) or the community Telegram group (opens in a new tab).
- If you suspect a bug, open an issue on GitHub (opens in a new tab).
Include the release, the log lines, and the output of
interfold node validate.