FuelLabs/fuel-core · error

The transaction has more outputs than allowed by the consens

Error message

The transaction has more outputs than allowed by the consensus

What it means

Thrown by the transaction assembler (the assembleTransaction GraphQL mutation, crates/fuel-core/src/schema/tx.rs) when the transaction bytes you submitted already contain more outputs than the chain allows. The limit comes from consensus parameters (tx_params.max_outputs), and AssembleTx::new rejects the transaction before doing any coin selection, fee estimation, or witness insertion.

Source

Thrown at crates/fuel-core/src/schema/tx/assemble_tx.rs:185

    dry_run_count: usize,
}

impl<'a, Tx> AssembleTx<'a, Tx>
where
    Tx: ExecutableTransaction + Cacheable + Send + 'static,
{
    pub fn new(tx: Tx, mut arguments: AssembleArguments<'a>) -> anyhow::Result<Self> {
        let max_inputs = arguments.consensus_parameters.tx_params().max_inputs();
        let max_outputs = arguments.consensus_parameters.tx_params().max_outputs();

        if tx.inputs().len() > max_inputs as usize {
            return Err(anyhow::anyhow!(
                "The transaction has more inputs than allowed by the consensus"
            ));
        }

        if tx.outputs().len() > max_outputs as usize {
            return Err(anyhow::anyhow!(
                "The transaction has more outputs than allowed by the consensus"
            ));
        }

        if arguments.fee_index as usize >= arguments.required_balances.len() {
            return Err(anyhow::anyhow!("The fee address index is out of bounds"));
        }

        if has_duplicates(&arguments.required_balances, |balance| {
            (balance.asset_id, balance.account.owner())
        }) {
            return Err(anyhow::anyhow!(
                "required balances contain duplicate (asset, account) pair"
            ));
        }

        let base_asset_id = *arguments.consensus_parameters.base_asset_id();
        let mut signature_witness_indexes = HashMap::<Address, u16>::new();

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Reduce the outputs in the submitted transaction: split into multiple transactions or drop unnecessary Change/Variable outputs (the assembler adds Change outputs itself)
  2. Query chainInfo.consensusParameters.txParameters.maxOutputs and assert your decoded tx's outputs length is under it before calling assembleTransaction
  3. If you operate the chain, raise max_outputs via a consensus parameter change

Example fix

// before
const res = await client.assembleTx(txBytes, { requiredBalances }); // tx has 300 outputs, node limit 255

// after
const max = chainInfo.consensusParameters.txParameters.maxOutputs; // 255
const tx = Transaction.fromBytes(txBytes);
while (tx.outputs.length > max) {
  tx.outputs.pop(); // or split into several transactions
}
const res = await client.assembleTx(tx.toBytes(), { requiredBalances });
Defensive patterns

Strategy: validation

Validate before calling

const info = await client.request(gql`{ chain { consensusParameters { txParameters { maxOutputs } } } }`);
const maxOutputs = Number(info.chain.consensusParameters.txParameters.maxOutputs);
const tx = Transaction.fromBytes(txBytes);
if (tx.outputs.length > maxOutputs) {
  throw new Error(`outputs ${tx.outputs.length} > maxOutputs ${maxOutputs}`);
}
await client.request(ASSEMBLE_TX, { tx: hexlify(txBytes), requiredBalances });

Type guard

function withinOutputLimit(decodedTx: { outputs: unknown[] }, maxOutputs: number): boolean {
  return decodedTx.outputs.length <= maxOutputs;
}

Try / catch

catch (e) { if (/more outputs than allowed by the consensus/.test(e.message)) { /* trim outputs and resubmit */ } else throw e; }

Prevention

When it happens

Trigger: Calling assembleTransaction with a transaction whose outputs array length exceeds tx_params.max_outputs (commonly 255). The initial tx you encode (script with pre-declared Variable/Change outputs, or a batch of transfers) already violates the limit before assembly adds anything.

Common situations: Batching many transfers into one tx; scripts declaring one Variable output per expected contract call; operating a chain with a lowered max_outputs consensus parameter; chains after a consensus-parameter upgrade with tighter limits.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/b974343f70375947. Report an issue: GitHub.