Enclave is now The Interfold.
Run a Ciphernode
Troubleshooting

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

SymptomSection
This node was NOT selected for sortition for each E3Not selected for committees
Failed to submit ticket: …Ticket submission fails
DHT put record failed: the quorum failed; needed 1 peersDHT put record fails
No connected peers, or Rejected an incompatible Interfold peerNo connected peers
E3 requests appear on-chain, but the node logs nothingThe node does not follow the chain
The node exits at startup with an errorStartup fails
The operating system kills the node or the prover during a DKGOut of memory

Read the logs

The CLI sets the log level with flags. See Global options.

FlagLevelUse
NoneWARNWarnings and errors only
-vINFONormal operation. Most log lines on this page need this level.
-vvDEBUGDetailed diagnosis of one problem
-vvvTRACEVery large output. Use it only for a short time.
-q, --quietERRORErrors 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 -v

The 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.

FieldExpected valueIf not
RegisteredtrueRegister the operator. See Registration.
ActivetrueContinue with the next rows.
Exit pendingfalseA deregistration is in progress. The operator cannot enter committees.
Ticket balanceThe available count is at least minTicketsBuy tickets.
Ciphernode bondAt 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) on SlashingManager.

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 at requestBlock - 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 messageCauseAction
CommitteeDeadlineReachedThe transaction arrived after the committee deadline.Use a faster RPC endpoint. The window is sortitionSubmissionWindow after the VRF response.
NodeNotEligibleThe operator was not active, or had no tickets at the snapshot.Check the status as in Not selected for committees.
InvalidTicketNumberThe 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 empty success list therefore means that no peer acknowledged the request at all.
  • QuorumFailed, not Timeout. The Kademlia query timeout is 60 s. A QuorumFailed result 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

  1. 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.
  2. 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 different protocol_version, one more enabled chain, or a different interfold address changes the string. Every peer then rejects the node, and the node logs Rejected an incompatible Interfold peer with the reason.
  3. 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 lineLevelMeaning
Found <n> peer(s) to dial:INFOThe peers from the configuration and the network profile.
Peer admittedINFOA peer passed the Identify check.
Rejected an incompatible Interfold peerINFOThe Identify check failed. The reason field gives the cause.
Evicting unreachable peer <peer> after 3 consecutive failuresINFOThree dials to the peer failed in a row.
Incoming connection error: …WARNAn inbound connection failed.
Peer did not complete Identify before the admission deadlineDEBUGA 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 lineCauseAction
Found 0 peers to dialThe 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 failuresThe peer does not answer at its address.Check the address and that the peer runs.
Rejected a configured peer whose pinned identity changedThe 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 continueA 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 subscriptionA 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

MessageCauseAction
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 dependenciesThe 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

Next steps