linera-io/linera-protocol · error · anyhow

L2 partial sync: local sync failed ({category})

Error message

L2 partial sync: local sync failed ({category})

What it means

The opt-in `--deep` partial-sync layer first synchronizes the local chain client (`chain_client.synchronize_chain_state(chain)`) under the RPC timeout. If that sync fails, the categorized error (timeout, node error, etc.) is embedded in the bail and the benchmark aborts. Per the module docs, on a tall chain the wallet does not track, this local sync can exceed `--rpc-timeout-secs` because it downloads all certificates up to the local tip.

Source

Thrown at linera-service/src/cli/validator_benchmark/partial_sync.rs:66

        duration_secs: 0.0,
        blocks_per_sec: 0.0,
    };

    let chain_client = context.make_chain_client(chain).await?;

    // The local sync can be heavy (it downloads the certificates to push); give
    // it a visible spinner so it never looks frozen. NOTE: on a tall chain the
    // wallet does not track, this can exceed --rpc-timeout-secs; raise it or use
    // a tracked chain if the seed times out here.
    let sync_phase = progress.phase("L2 partial sync: local state", None);
    let local_tip = match timed(rpc_timeout, chain_client.synchronize_chain_state(chain)).await {
        Ok(info) => {
            sync_phase.finish_ok();
            info.next_block_height.0
        }
        Err(category) => {
            sync_phase.finish_fail();
            anyhow::bail!("L2 partial sync: local sync failed ({category})");
        }
    };

    // The candidate may not yet know the chain at all (BlobsNotFound -> 0).
    let candidate_tip = match timed(
        rpc_timeout,
        node.handle_chain_info_query(linera_core::data_types::ChainInfoQuery::new(chain)),
    )
    .await
    {
        Ok(response) => response.info.next_block_height.0,
        Err(_) => 0,
    };

    let from = candidate_tip;
    let to = end_height(candidate_tip, max_blocks, local_tip);
    report.from_height = from;
    report.to_height = to;

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Raise the timeout: pass a larger --rpc-timeout-secs (the sync downloads certificates up to the local tip)
  2. Benchmark a chain the wallet tracks (add/follow the chain first) so local sync is cheap
  3. Read the category in the message — non-timeout categories (e.g. node errors) indicate something to fix on the node side first
  4. Run without --deep if the write-path (push) measurement is not needed

Example fix

# before
linera validator benchmark <addr> --chain <id> --deep --rpc-timeout-secs 30

# after
linera validator benchmark <addr> --chain <id> --deep --rpc-timeout-secs 300
Defensive patterns

Strategy: retry

Validate before calling

// Cheap guard: make sure the wallet tracks the chain before a deep run.
let wallet = options.wallet()?;
anyhow::ensure!(
    wallet.chain_ids().contains(&chain_id),
    "chain {chain_id} not tracked by the wallet; local sync will re-download the whole chain"
);

Try / catch

match partial_sync::run(&node, &ctx, chain, max_blocks, rpc_timeout, &progress).await {
    Err(e) if e.to_string().contains("L2 partial sync: local sync failed") => {
        // most common cause is rpc_timeout too small for a tall untracked chain:
        // raise --rpc-timeout-secs and retry, or track the chain first
        retry_with(rpc_timeout * 4).await?;
    }
    result => result?,
}

Prevention

When it happens

Trigger: Running `validator-benchmark --deep` where the local `synchronize_chain_state` call exceeds `--rpc-timeout-secs` or errors out — typically a tall chain that the wallet does not track, or a slow/unreachable local node.

Common situations: Deep-benchmarking a long-running chain with the default RPC timeout; benchmarking client with slow disk/network; the seed chain not present in the wallet.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/f6891d0655e4f0fd. Report an issue: GitHub.