FuelLabs/fuel-core · error · Error::Serialization

Missing output_contract on mint transaction

Error message

Missing output_contract on mint transaction

What it means

The Mint transaction conversion needs both a contract input and a contract output; this error fires when the proto mint message has output_contract unset. It is a hard failure (Error::Serialization) raised before FuelTransaction::mint is constructed, because the fuel-core Mint type requires the output contract.

Source

Thrown at crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs:684

            );

            Ok(FuelTransaction::Create(create_tx))
        }
        ProtoTransactionVariant::Mint(proto_mint) => {
            let tx_pointer_proto = proto_mint.tx_pointer.as_ref().ok_or_else(|| {
                Error::Serialization(anyhow!("Missing tx_pointer on mint transaction"))
            })?;
            let tx_pointer = tx_pointer_from_proto(tx_pointer_proto)?;
            let input_contract_proto =
                proto_mint.input_contract.as_ref().ok_or_else(|| {
                    Error::Serialization(anyhow!(
                        "Missing input_contract on mint transaction"
                    ))
                })?;
            let input_contract = contract_input_from_proto(input_contract_proto)?;
            let output_contract_proto =
                proto_mint.output_contract.as_ref().ok_or_else(|| {
                    Error::Serialization(anyhow!(
                        "Missing output_contract on mint transaction"
                    ))
                })?;
            let output_contract = contract_output_from_proto(output_contract_proto)?;
            let mint_asset_id = fuel_core_types::fuel_types::AssetId::try_from(
                proto_mint.mint_asset_id.as_slice(),
            )
            .map_err(|e| Error::Serialization(anyhow!(e)))?;

            let mint_tx = FuelTransaction::mint(
                tx_pointer,
                input_contract,
                output_contract,
                proto_mint.mint_amount,
                mint_asset_id,
                proto_mint.gas_price,
            );

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Fix the producer to always set output_contract on mint transactions and re-encode the affected blocks
  2. Align proto definitions (protobuf_types.rs) between producer and consumer versions
  3. Validate mint messages up front and quarantine blocks containing incomplete mint transactions instead of failing the whole stream
  4. Re-encode legacy data through a migration that derives the output contract from the input contract's contract_id

Example fix

// before
if let Some(mint) = variant_as_mint(&proto_tx) { convert_mint(mint)?; } // fails mid-way

// after
fn mint_is_complete(m: &ProtoMint) -> bool {
    m.tx_pointer.is_some() && m.input_contract.is_some() && m.output_contract.is_some()
}
if mint_is_complete(&mint) { convert_mint(&mint)?; } else { skip_and_report(&proto_tx); }
Defensive patterns

Strategy: validation

Validate before calling

fn mint_tx_is_complete(m: &ProtoMint) -> bool {
    m.tx_pointer.is_some() && m.input_contract.is_some() && m.output_contract.is_some()
}

Type guard

fn has_output_contract(m: &ProtoMint) -> bool { m.output_contract.is_some() }

Try / catch

if let Err(e) = convert_transaction(&proto_tx) {
    if e.to_string().contains("Missing output_contract on mint") {
        metrics::incomplete_mint_tx.inc(); quarantine(proto_tx.id());
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: A ProtoTransactionVariant::Mint arrives with input_contract present but output_contract None (or both unset — this error surfaces once input checks pass). Typical with partial encoders or schema-skew between block source and aggregator.

Common situations: Producer node built with a proto version where mint output_contract was optional/newly added; truncated or hand-crafted proto payloads; replaying legacy archived blocks.

Related errors


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