{"record":{"id":"fa9a6659c3a6d16b","repo":"FuelLabs/fuel-core","slug":"the-block-has-more-than-u16-max-transactions","errorCode":null,"errorMessage":"The block has more than `u16::MAX` transactions, {}","messagePattern":"The block has more than `u16::MAX` transactions, (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/graphql_api/worker_service.rs","lineNumber":367,"sourceCode":"\n    Ok(())\n}\n\n/// Associate all transactions within a block to their respective UTXO owners\nfn index_tx_owners_for_block<T>(\n    block: &Block,\n    block_st_transaction: &mut T,\n    chain_id: &ChainId,\n) -> anyhow::Result<()>\nwhere\n    T: OffChainDatabaseTransaction,\n{\n    for (tx_idx, tx) in block.transactions().iter().enumerate() {\n        let block_height = *block.header().height();\n        let inputs;\n        let outputs;\n        let tx_idx = u16::try_from(tx_idx).map_err(|e| {\n            anyhow::anyhow!(\"The block has more than `u16::MAX` transactions, {}\", e)\n        })?;\n        let tx_id = tx.id(chain_id);\n        match tx {\n            Transaction::Script(tx) => {\n                inputs = tx.inputs().as_slice();\n                outputs = tx.outputs().as_slice();\n            }\n            Transaction::Create(tx) => {\n                inputs = tx.inputs().as_slice();\n                outputs = tx.outputs().as_slice();\n            }\n            Transaction::Mint(_) => continue,\n            Transaction::Upgrade(tx) => {\n                inputs = tx.inputs().as_slice();\n                outputs = tx.outputs().as_slice();\n            }\n            Transaction::Upload(tx) => {\n                inputs = tx.inputs().as_slice();","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/graphql_api/worker_service.rs#L349-L385","documentation":"The off-chain worker indexes each transaction's position in a block as a u16 (the owned-transaction index layout reserves 2 bytes for tx_idx). enumerate() yields a usize, and u16::try_from fails when a block contains more than 65535 transactions. Consensus limits keep valid Fuel blocks far below this, so the error indicates a hand-crafted or malformed block rather than normal chain data.","triggerScenarios":"Processing (importing/executing) a block whose transactions() iterator yields more than u16::MAX items — custom-built blocks, fuzzing, or a changed protocol limit not reflected in the index layout.","commonSituations":"Test/fuzz environments injecting oversized blocks; local dev chains with relaxed limits; future consensus parameter changes raising max txs per block.","solutions":["Reject the block before processing if block.transactions().len() > u16::MAX.","For test chains, cap transactions per block below 65535.","If raising the real limit is required, the index key layout (2-byte tx_idx) must be widened — a coordinated storage-format change."],"exampleFix":"// before\nlet tx_idx = u16::try_from(tx_idx)?;\n\n// after\nif block.transactions().len() > u16::MAX as usize {\n    anyhow::bail!(\"block exceeds maximum supported transaction count\");\n}\nlet tx_idx = u16::try_from(tx_idx)?;","handlingStrategy":"validation","validationCode":"// Reject oversized blocks before execution/indexing.\nif block.transactions().len() > u16::MAX as usize {\n    anyhow::bail!(\n        \"block {} has {} transactions; max supported is {}\",\n        block.header().height(),\n        block.transactions().len(),\n        u16::MAX\n    );\n}","typeGuard":"fn is_indexable_block(block: &Block) -> bool {\n    block.transactions().len() <= u16::MAX as usize\n}","tryCatchPattern":"match process_block(&block, &mut tx, &chain_id) {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"u16::MAX transactions\") => {\n        // malformed/hand-crafted block: reject it, never retry\n        Err(anyhow::anyhow!(\"rejecting malformed block: {}\", e))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Enforce a consensus/config transaction-count limit well below 65535 on custom chains.","Treat this error as evidence of a crafted block, not of a node bug.","Widen the 2-byte tx_idx index layout before ever raising limits in production."],"tags":["off-chain","worker","validation","transactions","rust"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}