nautechsystems/nautilus_trader · error

Unsupported instrument type for futures fill report

Error message

Unsupported instrument type for futures fill report

What it means

Kraken Futures fill report parsing extracts the quote currency from the instrument to construct the commission Money. Only CryptoPerpetual and CryptoFuture variants are supported; any other instrument kind bails with this message.

Source

Thrown at crates/adapters/kraken/src/common/parse.rs:1094

pub fn parse_futures_fill_report(
    fill: &FuturesFill,
    instrument: &InstrumentAny,
    account_id: AccountId,
    ts_init: UnixNanos,
) -> anyhow::Result<FillReport> {
    let instrument_id = instrument.id();
    let venue_order_id = VenueOrderId::new(&fill.order_id);
    let trade_id = TradeId::new(&fill.fill_id);

    let order_side = fill.side.into();

    let last_qty = Quantity::from_decimal_dp(fill.size, instrument.size_precision())?;
    let last_px = Price::from_decimal_dp(fill.price, instrument.price_precision())?;

    let quote_currency = match instrument {
        InstrumentAny::CryptoPerpetual(perp) => perp.quote_currency,
        InstrumentAny::CryptoFuture(future) => future.quote_currency,
        _ => anyhow::bail!("Unsupported instrument type for futures fill report"),
    };

    let commission = Money::from_decimal(fill.fee_paid.unwrap_or(Decimal::ZERO), quote_currency)?;

    let liquidity_side = fill.fill_type.into();

    let ts_event = parse_rfc3339_timestamp(&fill.fill_time, "fill.fill_time")?;

    Ok(FillReport {
        account_id,
        instrument_id,
        venue_order_id,
        trade_id,
        order_side,
        last_qty,
        last_px,
        commission,
        liquidity_side,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the fill's instrument_id is a Futures (perpetual or dated future) symbol like 'PF_XBTUSD' or 'FI_...'.
  2. Ensure the instrument was parsed/loaded via parse_futures_instrument, not the Spot parser.
  3. Route the fill report through parse_fill_report instead if the instrument is actually a Spot instrument.

Example fix

// before (wrong parser for a spot pair)
let report = parse_futures_fill_report(fill, &currency_pair_instrument)?;
// after
let report = parse_fill_report(fill, &currency_pair_instrument)?;
Defensive patterns

Strategy: type-guard

Validate before calling

let is_futures = matches!(instrument,
    InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CryptoFuture(_));
if !is_futures { eprintln!("{}: not a futures instrument; use spot fill parser", instrument.id()); }

Type guard

fn supports_futures_fill_report(inst: &InstrumentAny) -> bool {
    matches!(inst, InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CryptoFuture(_))
}

Try / catch

match parse_futures_fill_report(&fill, instrument) {
    Ok(r) => push(r),
    Err(e) if e.to_string().contains("Unsupported instrument type") => route_to_spot_parser(&fill)?,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: parse_futures_fill_report (called by request_fill_reports) processes a fill whose instrument resolves to something other than CryptoPerpetual or CryptoFuture — e.g. a CurrencyPair or TokenizedAsset instrument registered under the Futures client.

Common situations: Spot and Futures instruments mixed in one cache/catalog; fills arriving for instruments parsed by the wrong adapter branch; future instrument kinds added upstream but not handled here.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/7440e23011a45b5f. Report an issue: GitHub.