linera-io/linera-protocol · error
keystore does not contain a key for owner {chain_owner}
Error message
keystore does not contain a key for owner {chain_owner} What it means
The relayer loaded the keystore but it holds no private key for the configured bridge chain owner. After syncing the admin chain, run() verifies signer.contains_key(&chain_owner) because every bridge block on the relayed chain must be signed with that owner's key; the check fails closed at startup instead of failing per block later.
Source
Thrown at linera-bridge/src/relay/mod.rs:177
wallet,
signer.clone(),
&Default::default(),
None,
genesis_config,
linera_core::worker::DEFAULT_BLOCK_CACHE_SIZE,
linera_core::worker::DEFAULT_EXECUTION_STATE_CACHE_SIZE,
))
.await?;
// ── Sync admin chain ──
tracing::info!(%admin_chain_id, "Syncing admin chain from validators...");
let admin_client = ctx.make_chain_client(admin_chain_id).await?;
admin_client.synchronize_from_validators().await?;
let admin_chain_height = admin_client.chain_info().await?.next_block_height;
tracing::info!(%admin_chain_height, "Admin chain synced");
// ── Register bridge chain in the local wallet ──
anyhow::ensure!(
signer
.contains_key(&chain_owner)
.await
.context("failed to query keystore")?,
"keystore does not contain a key for owner {chain_owner}"
);
ctx.update_wallet_for_new_chain(
chain_id,
Some(chain_owner),
linera_base::data_types::Timestamp::default(),
linera_base::data_types::Epoch::ZERO,
)
.await?;
ctx.client
.extend_chain_mode(chain_id, linera_core::client::ListeningMode::FullChain);
View on GitHub (pinned to 6c226ddcb3)
Solutions
- Print the owner the relayer expects (it appears in the error and in the "bridge chain" config) and compare it with the owners in keystore.json.
- Import or generate the owner's key into the keystore used at startup (keygen + add to keystore.json, or copy the matching keystore from the setup machine).
- If the key is genuinely lost, re-register the bridge chain with a new owner that this keystore controls and update the relayer config.
- Verify you passed --keystore pointing at the same keystore used during bridge setup.
Example fix
# before: keystore.json has no entry for the configured chain owner linera-bridge-relay run --keystore /etc/linera/keystore.json --chain-owner <owner> # after: generate/import the owner key into that keystore first linera keygen # (or paste the owner's secret key into keystore.json) linera-bridge-relay run --keystore /etc/linera/keystore.json --chain-owner <owner>
Defensive patterns
Strategy: validation
Validate before calling
let keystore = linera_wallet_json::Keystore::read(&keystore_path)?;
let owner: AccountOwner = bridge_config.chain_owner;
ensure!(
keystore.contains_key(&owner).await?,
"owner {owner} missing from keystore — import the key before starting"
); Prevention
- Keep keystore.json and the bridge config together when copying setups between machines.
- Verify owner↔key mapping after any keygen or chain re-registration.
- Automate the contains_key check in deployment preflight scripts.
When it happens
Trigger: chain_owner (from the bridge configuration) does not match any AccountOwner in keystore.json: keystore generated for a different owner, owner key never imported, or a bridge config created against another machine's keystore.
Common situations: Copying bridge config files between machines without copying keystore.json; regenerating the chain owner key during setup; mixing testnet/mainnet keystores; typos when passing the owner argument.
Related errors
- Invalid address length: {s}
- Invalid address value: {s}
- Keystore already exists: {}
- invalid tx hash: {}
- no admin chain (Root(0)) in genesis config
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/fc25476bcdfff06e.
Report an issue: GitHub.