linera-io/linera-protocol · error · ChainError
Block proposal has size {0} which is too large
Error message
Block proposal has size {0} which is too large What it means
ProposedBlock::check_proposal_size (linera-chain/src/data_types/mod.rs:141-148) bcs-serializes the block and rejects it if it exceeds the committee policy's maximum_block_proposal_size — 13,000,000 bytes in the default production policy (linera-execution/src/policy.rs:326), u64::MAX in the test default (policy.rs:241). Both stage_block_execution (linera-core/src/chain_worker/state.rs:2424) and try_handle_block_proposal (state.rs:2529) enforce the limit, so oversized proposals never execute.
Source
Thrown at linera-chain/src/data_types/mod.rs:143
pub fn operations(&self) -> impl Iterator<Item = &Operation> {
self.transactions.iter().filter_map(|tx| match tx {
Transaction::ExecuteOperation(operation) => Some(operation),
Transaction::ReceiveMessages(_) => None,
})
}
/// Returns all incoming bundles in this block.
pub fn incoming_bundles(&self) -> impl Iterator<Item = &IncomingBundle> {
self.transactions.iter().filter_map(|tx| match tx {
Transaction::ReceiveMessages(bundle) => Some(bundle),
Transaction::ExecuteOperation(_) => None,
})
}
/// Checks that the serialized size of this block does not exceed the given maximum.
pub fn check_proposal_size(&self, maximum_block_proposal_size: u64) -> Result<(), ChainError> {
let size = bcs::serialized_size(self)?;
ensure!(
size <= usize::try_from(maximum_block_proposal_size).unwrap_or(usize::MAX),
ChainError::BlockProposalTooLarge(size)
);
Ok(())
}
}
#[async_graphql::ComplexObject]
impl ProposedBlock {
/// Metadata about the transactions in this block.
async fn transaction_metadata(&self) -> Vec<TransactionMetadata> {
self.transactions
.iter()
.map(TransactionMetadata::from_transaction)
.collect()
}
}
View on GitHub (pinned to 6c226ddcb3)
Solutions
- Split the block into several smaller proposals at the same or successive heights
- Publish large data as blobs through the blob-storage flow first and reference them by BlobId in the block instead of inlining the bytes
- If you operate the committee, raise maximum_block_proposal_size in the policy (genesis config or policy update path)
Example fix
// before: inlining a big blob's bytes into the block
let block = ProposedBlock { transactions: vec![Transaction::ExecuteOperation(
Operation::system(SystemOperation::PublishDataBlob(blob_bytes)),
)], .. };
// after: publish via blob service, reference by id in (smaller) blocks
let blob_id = client.publish_data_blob(blob_bytes).await?; // stored out-of-band
let block = ProposedBlock { transactions: vec![Transaction::ExecuteOperation(
Operation::system(SystemOperation::PublishBlob { blob_id }),
)], .. }; Defensive patterns
Strategy: validation
Validate before calling
// Cheap pre-submit mirror of check_proposal_size (data_types/mod.rs:141):
let size = bcs::serialized_size(&block)?;
let limit = usize::try_from(policy.maximum_block_proposal_size).unwrap_or(usize::MAX);
if size > limit {
anyhow::bail!("block proposal is {size} bytes > limit {limit}; split it or use blobs");
} Try / catch
match result {
Err(ChainError::BlockProposalTooLarge(size)) => {
// split the block, or move large payloads to the blob service and reference
// BlobIds; retrying the identical block cannot succeed
}
other => other?,
} Prevention
- Publish large data via the blob service; reference blobs by id in blocks
- Batch operations into multiple blocks instead of one maximal block
- Know your committee's maximum_block_proposal_size (default 13 MB in production policy)
When it happens
Trigger: Blocks inlining large published blobs or many big transactions (check_proposal_size counts the whole serialized ProposedBlock); a committee that lowered maximum_block_proposal_size (it is configurable via genesis/policy, linera-service/src/cli/command.rs:317); tests deliberately setting tiny limits (e.g., fee_consumption.rs uses 61 bytes).
Common situations: Publishing large data (images, WASM bytecode, state blobs) inside the block instead of via the blob service; batch jobs packing thousands of operations into one block; a policy change shrinking limits while old batching logic remained.
Related errors
- Must contain a validation certificate if and only if it cont
- TooManyPublishedBlobs
- Default wallet directory is not supported in this platform:
- nonexistent chain `{chain_id}`
- keypair not found for chain `{chain_id}`
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/193b556ecb3ecb83.
Report an issue: GitHub.