xOneRS refuses to open a datadir for a chain it was not made for. A file in the datadir, the chain marker, records the chain id, the genesis hash and, since PR #954 (merged 2026-11-14), the whole consensus schedule. Every start compares the marker with the chain it is asked to run, before the store opens. Peers on another network are refused at the handshake.
This post covers the marker, the schedule check and the --chainspec.update flag. For the checks on a peer's chain history, see peer chain verification.
What is the chain marker?
The marker is xone-chain.json in the datadir. xone init and the first start write it; every later start must match it, so a datadir made for chain X cannot be opened as chain Y (datadir.rs). It holds:
chain_idandgenesis_hash,schedule: every consensus rule by name, each with the block it applies from.
The schedule has three groups: the fork rows (fork.<name>), the effective activations (effective.<name>) and the XDPoS parameters (xdpos.<name>). V1 parameters apply from block 0. The V2 per-round configurations count from the V2 switch block.
Marker writes are atomic (a temporary file, then a rename). Nothing is written when a start is refused (PR #954).
What happens if I start a datadir on another chain?
The start stops with an error and changes nothing. The text is:
datadir was initialised for chain <have> (genesis <hash>); refusing to use it for chain <want> (genesis <hash>)
A --networkid that differs from the genesis chain id is refused too: --networkid <n> does not match the genesis chain id <m>. A --chainspec file is for private chains only; for a public chain id the node refuses it, because a public chain has only its built-in spec.
What happens if the consensus rules change?
The node reads the store head read-only from chain.mdbx and compares the recorded schedule with the new one before anything opens. Two cases differ:
| Change | Result |
|---|---|
| A rule the chain already applies at its head changes | Always refused: "the chain was made under the recorded rules and cannot run under these" |
| Every change lies ahead of the head | Refused unless you pass --chainspec.update; with the flag the new schedule is recorded |
Each changed rule is listed as <rule> <old> -> <new>, with (active) when it already applies. On the built-in networks the flag is implicit, because their rules ship with the build (flags.md, --chainspec.update row).
A marker written before PR #954 has no schedule. The next start records it.
PR #954 records its tests: an Apothem datadir with a changed epoch was refused (the change applies at head 0), and a private chain 777 with Shanghai moved ahead was refused without the flag and recorded with it.
How are peers from another network refused?
The status message of eth/100 and eth/101 carries the network id and the genesis hash. A received status is checked in this order: network id, protocol version, genesis hash. The first failure ends the connection (spec/net/status62.md). On Apothem a peer must also hold the built-in required block; see peer chain verification.
How do other clients describe this?
The collected competitor articles state no claim about a datadir chain marker or a recorded consensus schedule, so this post has no comparison table. geth-XDC has no --chainspec.update flag; the flag table marks it "not in geth-XDC; xone-defined".
What should an operator do with a refusal?
- Chain mismatch: point
--datadirat the right directory, or start a new one. Do not edit the marker. - Active schedule change: the datadir belongs to the old rules. Resync under the new rules in a new datadir.
- Change ahead of the head on a private chain: check the new spec, then start once with
--chainspec.update.
For upgrades in general, see how to upgrade or roll back.
Frequently asked questions
Where does xOne record which chain a datadir belongs to?
In xone-chain.json in the datadir: the chain id, the genesis hash and, since PR #954, the consensus schedule with the block each rule applies from.
Can I open an Apothem datadir as net2040?
No. The marker's chain id and genesis hash differ, so the start is refused and nothing is written.
When do I need --chainspec.update?
When a private chain's spec changes only at blocks ahead of the datadir's head. On the built-in networks it is implicit. A change at a rule that already applies is refused even with the flag.
Does the v0.1.0 release check the schedule?
No. The schedule check came in PR #954, merged on 2026-11-14, after v0.1.0. A marker from an older build records its schedule on the next start of a newer build.
Sources
- PR #954: record the consensus schedule and refuse incompatible changes (closes #444)
- crates/xone-node/src/datadir.rs
- docs/cli/flags.md (
--chainspec.update,--networkid,--override.genesis) - spec/net/status62.md
This article describes the source and evidence at its review date. Check the linked repository for current implementation and qualification status.
Explore the engineering evidenceEdit this page on GitHub opens the Markdown source (content/blog/wrong-network-refusal/index.md). GitHub may ask you to sign in. Report a correction opens a prefilled GitHub issue for this page.