{"record":{"id":"3c07660b095b4ff8","repo":"linera-io/linera-protocol","slug":"blocktoolarge","errorCode":"BlockTooLarge","errorMessage":"ExecutionError::BlockTooLarge","messagePattern":"ExecutionError::BlockTooLarge","errorType":"exception","errorClass":"ExecutionError","httpStatus":null,"severity":"error","filePath":"linera-execution/src/resources.rs","lineNumber":840,"sourceCode":"}\n\nimpl<Account, Tracker> ResourceController<Account, Tracker>\nwhere\n    Tracker: AsMut<ResourceTracker>,\n{\n    /// Tracks the serialized size of a block, or parts of it.\n    pub fn track_block_size_of(&mut self, data: &impl Serialize) -> Result<(), ExecutionError> {\n        self.track_block_size(bcs::serialized_size(data)?)\n    }\n\n    /// Tracks the serialized size of a block, or parts of it.\n    pub fn track_block_size(&mut self, size: usize) -> Result<(), ExecutionError> {\n        let tracker = self.tracker.as_mut();\n        tracker.block_size = u64::try_from(size)\n            .ok()\n            .and_then(|size| tracker.block_size.checked_add(size))\n            .ok_or(ExecutionError::BlockTooLarge)?;\n        ensure!(\n            tracker.block_size <= self.policy.maximum_block_size,\n            ExecutionError::BlockTooLarge\n        );\n        Ok(())\n    }\n}\n\nimpl ResourceController<Option<AccountOwner>, ResourceTracker> {\n    /// Provides a reference to the current execution state and obtains a temporary object\n    /// where the accounting functions of [`ResourceController`] are available.\n    pub async fn with_state<'a, C>(\n        &mut self,\n        view: &'a mut SystemExecutionStateView<C>,\n    ) -> Result<ResourceController<Sources<'a>, &mut ResourceTracker>, ViewError>\n    where\n        C: Context + Clone + 'static,\n    {\n        self.with_state_and_grant(view, None).await","sourceCodeStart":822,"sourceCodeEnd":858,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-execution/src/resources.rs#L822-L858","documentation":"track_block_size accumulates the serialized size of block contents (fed by track_block_size_of during block construction); exceeding maximum_block_size, or overflowing the u64 accumulator, fails with BlockTooLarge (resources.rs:840). Oversized blocks are rejected before they can be proposed, keeping block propagation and storage bounded.","triggerScenarios":"Building a block whose BCS-serialized operations and messages exceed the policy's maximum_block_size; also any size accounting addition that overflows the u64 total.","commonSituations":"Blocks bundling many operations or inlining large payloads; high-throughput producers that do not batch-limit; policies tightened in a new epoch; blob content referenced inline instead of by blob id.","solutions":["Split the block: propose smaller batches of operations","Move large payloads into blobs and reference them by BlobId instead of inlining the bytes","If you operate the network, raise maximum_block_size in the resource policy"],"exampleFix":"// before: inline large payload in an operation\nlet op = Operation::Upload(data.to_vec());\n\n// after: publish blob first, reference by id\nlet blob_id = publish_blob(data).await?;\nlet op = Operation::Reference(blob_id);","handlingStrategy":"validation","validationCode":"// Track serialized sizes while building the block; stop before exceeding the cap\nfn fits_block_size(ops: &[Operation], policy: &ResourceControlPolicy) -> Result<bool, Error> {\n    let size: usize = ops.iter().map(bcs::serialized_size).sum::<Result<usize, _>>()?;\n    Ok(size as u64 <= policy.maximum_block_size)\n}\n\nif !fits_block_size(&pending_ops, policy)? {\n    pending_ops.truncate(pending_ops.len() - 1); // shed operations until it fits\n}","typeGuard":"fn is_block_too_large(err: &ExecutionError) -> bool {\n    matches!(err, ExecutionError::BlockTooLarge)\n}","tryCatchPattern":"match proposer.propose(block).await {\n    Ok(h) => h,\n    Err(ref e) if is_block_too_large(e) => {\n        // fallback: split the block and propose the halves sequentially\n        let (a, b) = block.operations.split_at(block.operations.len() / 2);\n        propose_all(vec![a.to_vec(), b.to_vec()]).await\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Compute bcs::serialized_size while assembling blocks and enforce the policy cap client-side","Store large payloads as blobs and reference them by BlobId instead of inlining bytes","Batch with a conservative maximum operations-per-block tuned to maximum_block_size"],"tags":["block","size-limit","resource-policy","linera"],"backgroundTag":"block-size-limit-exceeded","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}