linera-io/linera-protocol · error · WorkerError
TooManyPublishedBlobs
TooManyPublishedBlobs
Error message
Number of published blobs per block must not exceed {0} What it means
The committee's resource-control policy caps how many blobs a single block may publish (policy.maximum_published_blobs). In handle_pending_blob, while inserting blobs for a proposed-but-not-yet-validated block, the worker enforces count < policy.maximum_published_blobs before each insert. Exceeding the cap rejects the blob and fails the request with TooManyPublishedBlobs; the check is skipped only for blob sets already validated by a quorum.
Source
Thrown at linera-core/src/chain_worker/state.rs:2280
) -> Result<ChainInfoResponse, WorkerError> {
let mut was_expected = self
.chain
.pending_validated_blobs
.maybe_insert(&blob)
.await?;
for (_, mut pending_blobs) in self
.chain
.pending_proposed_blobs
.try_load_all_entries_mut()
.await?
{
if !pending_blobs.validated.get() {
let (_, committee) = self.chain.current_committee().await?;
let policy = committee.policy();
policy
.check_blob_size(blob.content())
.with_execution_context(ChainExecutionContext::Block)?;
ensure!(
u64::try_from(pending_blobs.pending_blobs.iterative_count().await?)
.is_ok_and(|count| count < policy.maximum_published_blobs),
WorkerError::TooManyPublishedBlobs(policy.maximum_published_blobs)
);
}
was_expected = was_expected || pending_blobs.maybe_insert(&blob).await?;
}
ensure!(was_expected, WorkerError::UnexpectedBlob);
self.save().await?;
self.chain_info_response().await
}
/// Returns a stored [`Certificate`] for the chain's block at the requested [`BlockHeight`].
///
/// Does not need `&mut self` because the chain is eagerly initialized when the
/// chain handle is created.
#[cfg(with_testing)]
#[instrument(skip_all, fields(View on GitHub (pinned to 6c226ddcb3)
Solutions
- Split the publication across several blocks so each stays within maximum_published_blobs.
- Before proposing, count the blob ids in the block against policy.maximum_published_blobs from the chain's committee info.
- If the workload legitimately needs more, have the committee raise maximum_published_blobs when creating or updating the committee configuration (e.g. --maximum-published-blobs).
Example fix
// before: one block publishes every blob
let mut builder = BlockBuilder::new(height, timestamp);
for blob in all_blobs {
builder = builder.with_published_blob(blob.id());
}
// after: chunk under the policy cap
let cap = policy.maximum_published_blobs as usize;
for chunk in all_blobs.chunks(cap) {
let mut builder = BlockBuilder::new(height, timestamp);
for blob in chunk {
builder = builder.with_published_blob(blob.id());
}
// confirm this block, then publish the next chunk
} Defensive patterns
Strategy: validation
Validate before calling
// Read the cap from the committee policy before building the block.
let (_, committee) = client.current_committee(chain_id).await?;
let max = committee.policy().maximum_published_blobs;
if u64::try_from(blob_ids.len()).is_ok_and(|n| n > max) {
return Err(WorkerError::TooManyPublishedBlobs(max));
} Try / catch
match node.handle_pending_blob(blob).await {
Err(NodeError::WorkerError(err)) if matches!(*err, WorkerError::TooManyPublishedBlobs(_)) => {
// Split the pending block: re-propose with fewer blobs and confirm in batches.
}
result => result,
} Prevention
- Publish blobs in batches well under the committee cap.
- Check the policy on chain info before generating blob-heavy blocks.
- Raise maximum_published_blobs deliberately at committee creation, not reactively after outages.
- Monitor this error: it usually indicates an application emitting unbounded blob growth.
When it happens
Trigger: handle_pending_blob (or send_pending_blobs / handle_message carrying a blob) for a proposal whose pending blob set has already reached policy.maximum_published_blobs; blocks from data-publishing applications that attach many blobs in one block.
Common situations: Genesis or committee policy configured with a low maximum_published_blobs; an application upgraded to publish more blobs per block; test chains using the default test policy cap of 10.
Related errors
- UnexpectedBlob
- ClosedChain
- CannotRejectMessage
- Block proposal has size {0} which is too large
- InvalidBlockChaining
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/e073d2154118d762.
Report an issue: GitHub.