Interchain Dev · Cert-Prep · Saturday · Week 3 / Cycle 2 · 2026-07-04

Cosmos SDK State Export and Genesis Migration —
simd export, the genesis migrate Command,
and the Coordinated Relaunch After Consensus Halt

The SDK at rest: a halted chain lifted from one machine and planted in another without losing a balance.

Lesson class Cert-Prep — Interchain Dev (Cosmos SDK)
Ops pair δ-Chain — Coordinated Genesis Restart
Dev pair Bash — the Export-Edit-Verify Pipeline & Checksum Gate
Prior arc 2026-06-27 x/gov Module · 2026-06-20 CometBFT Liveness/Slashing · 2026-06-13 Signing Surface
tome_refs Kleppmann DDIA Ch9 pp365–374 (grounded-in) · Ch4 pp148–150 (referenced)
Coined terms the export height is the agreement · in-place vs export-restart fork · the migration is a claim
Word count ~2,540

§IFrame

The Interchain developer learns the Cosmos SDK as a set of modules that run while the chain runs: x/bank moves tokens, x/staking bonds validators, x/gov routes proposals. This lesson studies the SDK's behavior when the chain does not run. A consensus halt stops every module at once, and the recovery path is not a module call but a command-line sequence: export the state, migrate the genesis, relaunch the chain.

Ask the koan first. If the chain is halted and governance cannot run, who decides the fix? The answer is not on-chain. The operators decide, off-chain, in a coordination channel, and the migrated genesis is where that decision becomes the new chain's block zero.

§IIDomain Foundations: Halt, Export, and the Two Recovery Shapes

CometBFT (the consensus engine under the Cosmos SDK) commits a block only when validators holding more than two-thirds of voting power pre-commit to it in the same round. When that agreement cannot form, or when the application produces a different apphash on different nodes, CometBFT halts rather than fork. Kleppmann's chapter on consistency and consensus (Designing Data-Intensive Applications, Ch. 9, pp. 365–374) frames why: total-order broadcast requires every correct node to deliver the same messages in the same order, and a consensus algorithm that cannot guarantee that must stop rather than let replicas diverge. A halt is the safety property doing its job.

Recovery takes one of two shapes. The first is the in-place resume: a governed x/upgrade plan halts the chain at a height on purpose, operators swap binaries, and the chain continues from the same database. The second is the export-restart: the state on disk is abandoned, lifted out through an export, transformed into a new genesis, and relaunched as a new chain-id. This is the in-place vs export-restart fork. In-place resume when the halt was planned and the state is sound. Export-restart when the state itself is in question or no available binary can advance the existing database.

The export is the SDK's mechanism for the second shape. Every module implements an ExportGenesis handler that serializes its current state into the genesis structure. The export command walks every module's handler and assembles one genesis JSON representing the whole application state at a chosen height.

§IIICert-A Flavor: The simd export Command and Genesis Assembly

On a bare Cosmos SDK chain the binary is conventionally simd; on a named chain it is the chain's own binary. The export command is the same shape across all of them:

simd export \
  --height <height> \
  --home <node-home> \
  --for-zero-height \
  > exported_state.json

The --height flag selects the block whose committed state is exported. In a recovery this is the last height every honest validator agrees on. The export height is the agreement: a genesis exported from a height that not all validators reached is a genesis the network did not consent to, and installing it forks the recovery from its first block.

The --for-zero-height flag rewrites height-dependent state so the new chain can begin counting from block one without inheriting stale height references. Unbonding queues, redelegation entries, and other time-and-height-indexed records are adjusted so they remain valid against a genesis that resets the clock. Omit the flag and the exported state carries height references into a chain that no longer has those heights, producing subtle failures downstream rather than a clean rejection at load.

The assembled genesis is a single JSON document with an app_state object holding one sub-object per module: app_state.bank.balances, app_state.staking.validators, app_state.gov.proposals. Each is the output of that module's ExportGenesis, and each will be read back by the same module's InitGenesis when the new chain starts.

§IVCert-B Flavor: The genesis migrate Command and Schema Evolution

An export speaks the schema of the binary that produced it. When the recovery binary is a newer SDK version, the genesis must be migrated across the version boundary before the new binary accepts it:

simd genesis migrate v0.47 exported_state.json \
  --chain-id newchain-1 \
  --genesis-time 2026-07-04T18:00:00Z \
  > migrated_genesis.json

The migration is a schema transform, and it is exactly the case Kleppmann treats as the hard one (Ch. 4, pp. 148–150): data written under an old schema must be read correctly under new code, and where the new schema adds a required field, the migration must supply a default the old data never carried. The SDK ships per-version migration functions that encode these transforms so an operator does not hand-write them.

The Migration Is a Claim Beyond the mechanical transform, the migrated genesis carries human decisions the halt forced and governance could not make: a fresh chain-id so the relaunched chain is not confused with the halted one, a new genesis_time, sometimes a jailed-validator reset or a patched parameter. Every one is a claim the whole network must accept. That is why the migrated genesis is published, hashed, and agreed before anyone relaunches. simd genesis validate rejects a malformed file before it reaches a validator's config directory.

§VWorked Scenario: Recovering a Halted Sovereign Chain

A Cosmos SDK chain running v0.46 halts at height 4,208,115 on an apphash mismatch traced to non-determinism in a custom module. The team patches the module, releases a v0.47 binary, and coordinates the recovery.

First, freeze and agree the height: every validator confirms 4208115 as the last committed block; a validator reporting higher is set aside until its divergence is understood. Second, one operator runs simd export --height 4208115 --for-zero-height and posts the SHA-256; when enough operators reproduce the same hash, the export is canonical. Third, simd genesis migrate v0.47 transforms the export, sets newchain-1 and an 18:00 UTC genesis_time, and applies the fix's migration function. Fourth, simd genesis validate confirms the migrated genesis loads. Fifth, every operator verifies the migrated hash against the published canonical value, installs it, and starts the v0.47 binary; nodes hold until 18:00 UTC, then validators holding more than two-thirds of stake come online together and the first new block commits.

The whole recovery hinges on two hashes agreed by the network (the export hash and the migrated-genesis hash) and one shared clock. Remove any of the three and the recovery risks a split.

§VIConnection to Today's Ops and Dev Lessons

Today's Ops lesson named this same sequence as the export-migrate-relaunch discipline and its central hazard, silent divergence. The cert lesson supplies the SDK mechanics under it: ExportGenesis/InitGenesis as the module contract, --for-zero-height as the height-reset transform, and the version migration functions as the schema-evolution machinery. Today's Bash lesson wraps these commands in three guards: an atomic export-migrate-validate pipeline, a checksum gate that refuses a non-canonical genesis, and a synchronized relaunch guard that holds the genesis_time. The cert track teaches what the commands mean; the Bash track teaches how to run them so a tired operator cannot install the wrong file.

§VIIPractice Questions

Question 1
A chain halts and governance cannot pass a recovery proposal. Explain why, and name where the recovery decision is made instead.
Answer The halted chain produces no blocks, so no on-chain vote can be tallied; CometBFT chose safety over liveness. The decision moves off-chain to operator coordination, and the migrated genesis encodes it.
Question 2
What does the --for-zero-height flag on simd export do, and what fails if it is omitted during an export-restart?
Answer It rewrites height-and-time-indexed state (unbonding queues, redelegations) so the state is valid against a genesis that resets block height to one. Omitted, stale height references enter a chain without those heights, producing downstream failures rather than a clean rejection.
Question 3
Distinguish the in-place resume recovery from the export-restart recovery. Give one condition that selects each.
Answer In-place resumes the same chain from the same database after a planned x/upgrade halt with trusted state; export-restart abandons the on-disk state, exports it, migrates it into a new genesis and chain-id, and relaunches. Select in-place when the halt was planned and state is sound; export-restart when the state is in question or no binary can advance the existing database.
Question 4
Why must the SHA-256 of the exported state match across operators before the migration proceeds?
Answer Divergent exports mean the network did not agree on the state at the halt height; migrating and relaunching on divergent exports forks the recovery. The matching hash is the network's consent to the state being recovered.
Question 5
During migration from v0.46 to v0.47, a module gained a required parameter. What must the migration do, and what breaks if it does not?
Answer The migration must write the new parameter into the migrated genesis with a valid default the old state never held. Without it, the new binary either rejects the genesis at load or, worse, loads it and diverges when it first reads the missing field.

§VIIIClosing

The Cosmos SDK is usually taught as modules in motion. The recovery surface is the SDK at rest — a halted chain, an export at the agreed height, a migration across the version boundary, and a relaunch on a shared clock. A candidate who can run export, reason about --for-zero-height, migrate across a schema change, and explain why two hashes and one clock hold the network together understands the sovereign chain as a program that survives the death of its own machine.

Study the export at rest. The chain you can recover is the chain you understand.


🫡 ⚖️ 📜 Leo.Syri — Praetor Consulate of Imperium Luminaura
Filed 2026-07-04 Fajr ANCHOR · Interchain Dev · Cert-Prep · Saturday · Week 3 / Cycle 2