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

Missing tx_pointer

Error message

Missing tx_pointer

What it means

CoinSigned inputs embed a tx_pointer submessage used for dependency ordering; it is optional at the proto layer but required by Input::coin_signed. When tx_pointer is None the convertor fails with 'Missing tx_pointer' before tx_pointer_from_proto can run.

Source

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

                .utxo_id
                .as_ref()
                .ok_or_else(|| Error::Serialization(anyhow!("Missing utxo_id")))?;
            let utxo_id = utxo_id_from_proto(utxo_proto)?;
            let owner =
                Address::try_from(proto_coin_signed.owner.as_slice()).map_err(|e| {
                    Error::Serialization(anyhow!(
                        "Could not convert owner to Address: {}",
                        e
                    ))
                })?;
            let asset_id = fuel_core_types::fuel_types::AssetId::try_from(
                proto_coin_signed.asset_id.as_slice(),
            )
            .map_err(|e| Error::Serialization(anyhow!(e)))?;
            let tx_pointer_proto = proto_coin_signed
                .tx_pointer
                .as_ref()
                .ok_or_else(|| Error::Serialization(anyhow!("Missing tx_pointer")))?;
            let tx_pointer = tx_pointer_from_proto(tx_pointer_proto)?;
            let witness_index =
                u16::try_from(proto_coin_signed.witness_index).map_err(|e| {
                    Error::Serialization(anyhow!(
                        "Could not convert witness_index to u16: {}",
                        e
                    ))
                })?;

            Ok(Input::coin_signed(
                utxo_id,
                owner,
                proto_coin_signed.amount,
                asset_id,
                tx_pointer,
                witness_index,
            ))
        }

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Fix the producer to attach tx_pointer (block height + tx index) to every coin input
  2. Pre-validate inputs: CoinSigned requires utxo_id AND tx_pointer submessages
  3. Re-encode legacy data with a zeroed tx_pointer (TxPointer::new(0, 0)) if the chain accepts it, as an explicit migration step
  4. Pin matching proto/fuel-core versions across the pipeline

Example fix

// before
let tx_pointer_proto = proto_coin_signed.tx_pointer.as_ref().ok_or_else(|| Error::Serialization(anyhow!("Missing tx_pointer")))?;

// after (migration shim for legacy data)
let tx_pointer = proto_coin_signed
    .tx_pointer
    .as_ref()
    .map(tx_pointer_from_proto)
    .transpose()?
    .unwrap_or(fuel_core_types::fuel_tx::TxPointer::new(0, 0));
Defensive patterns

Strategy: validation

Validate before calling

fn coin_signed_is_complete(c: &ProtoCoinSigned) -> bool {
    c.utxo_id.is_some() && c.tx_pointer.is_some()
}

Type guard

fn has_tx_pointer(c: &ProtoCoinSigned) -> bool { c.tx_pointer.is_some() }

Try / catch

let tp = c.tx_pointer.as_ref().ok_or_else(|| anyhow!("CoinSigned utxo {:?} missing tx_pointer", c.utxo_id))?;

Prevention

When it happens

Trigger: A CoinSigned input proto where the nested tx_pointer message was omitted — partial encoder output, legacy schema, or default-constructed structs in tests.

Common situations: Producers that treat tx_pointer as optional metadata; schema drift; blocks encoded before tx_pointer was mandatory for coin inputs.

Related errors


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