linera-io/linera-protocol · error · WorkerError
InvalidSigner
InvalidSigner
Error message
Operations in the block are not authenticated by the proper owner: {0} What it means
When a block's operations need owner authentication, the block records their signer in block.authenticated_owner. For a plain proposal (no original proposal attached), try_handle_block_proposal requires that signer to be exactly the owner who signed the proposal. InvalidSigner is raised when the two accounts differ: the operations were authenticated by someone other than the proposer.
Source
Thrown at linera-core/src/chain_worker/state.rs:2540
let chain = &self.chain;
// Check if the chain is ready for this new block proposal.
chain.tip_state.get().verify_block_chaining(block)?;
// Check the epoch.
let (epoch, committee) = chain.current_committee().await?;
check_block_epoch(epoch, block.chain_id, block.epoch)?;
let policy = committee.policy().clone();
block.check_proposal_size(policy.maximum_block_proposal_size)?;
// Check the authentication of the block.
ensure!(
chain.manager.can_propose(&owner, proposal.content.round),
WorkerError::InvalidOwner
);
let old_round = self.chain.manager.current_round();
match original_proposal {
None => {
if let Some(signer) = block.authenticated_owner {
// Check the authentication of the operations in the new block.
ensure!(signer == owner, WorkerError::InvalidSigner(owner));
}
}
Some(OriginalProposal::Regular { certificate }) => {
// Verify that this block has been validated by a quorum before.
certificate.check(&committee)?;
}
Some(OriginalProposal::Fast(signature)) => {
let original_proposal = BlockProposal {
content: ProposalContent {
block: content.block.clone(),
round: Round::Fast,
outcome: None,
},
signature: *signature,
original_proposal: None,
};
let super_owner = original_proposal.owner();
ensure!(View on GitHub (pinned to 6c226ddcb3)
Solutions
- Sign the proposal with the same account recorded in block.authenticated_owner.
- If the operations need no owner authentication, leave authenticated_owner as None.
- When reusing a block built elsewhere, rebuild the operation authentication under your own owner before signing.
Example fix
// before: block authenticated by app_owner, proposal signed by chain_owner let block = builder.with_authenticated_owner(app_owner).build()?; let proposal = block.into_proposal(&chain_owner_key); // after: authenticate and propose with the same owner let block = builder.with_authenticated_owner(chain_owner).build()?; let proposal = block.into_proposal(&chain_owner_key);
Defensive patterns
Strategy: validation
Validate before calling
if let Some(signer) = block.authenticated_owner {
ensure!(
signer == proposal.owner(),
WorkerError::InvalidSigner(proposal.owner())
);
} Try / catch
match node.handle_block_proposal(proposal).await {
Err(NodeError::WorkerError(err)) if matches!(*err, WorkerError::InvalidSigner(_)) => {
// Re-sign: make the proposal signer equal block.authenticated_owner,
// or clear authenticated_owner if the operations need no owner auth.
}
result => result,
} Prevention
- Use one key for both authenticating operations and signing the proposal, or none at all.
- Do not hand a built block to a different owner to sign without rebuilding its authentication.
- Assert signer == owner in client code before submitting; the error only surfaces the expected owner.
When it happens
Trigger: A client that builds the block (authenticating its operations) with one account but signs the BlockProposal with another; re-signing a proposed block originally created by a different owner without clearing or updating authenticated_owner.
Common situations: Multi-key wallets that split block building from proposal signing; applications whose operations are authenticated by an application account while the chain owner signs the proposal.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/2d73d73800d16717.
Report an issue: GitHub.