nautechsystems/nautilus_trader · error

Mark prices not available for Spot instruments

Error message

Mark prices not available for Spot instruments

What it means

This error is raised when subscribing to mark prices for a Spot instrument on Bybit. Bybit's WebSocket does not provide mark-price streams for Spot product types, so the adapter rejects the subscription early. The subscription is only valid for Linear, Inverse, and Option instruments.

Source

Thrown at crates/adapters/bybit/src/data.rs:1170

                async move {
                    ws.subscribe_ticker(instrument_id)
                        .await
                        .context("ticker subscription for funding rates")
                },
                "funding rate subscription",
            );
        }
        Ok(())
    }

    fn subscribe_mark_prices(&mut self, cmd: SubscribeMarkPrices) -> anyhow::Result<()> {
        let instrument_id = cmd.instrument_id;
        let product_type = self
            .get_product_type_for_instrument(instrument_id)
            .unwrap_or(BybitProductType::Linear);

        if product_type == BybitProductType::Spot {
            anyhow::bail!("Mark prices not available for Spot instruments");
        }

        let mut should_subscribe = false;
        self.ticker_subs.rcu(|m| {
            let entry = m.entry(instrument_id).or_default();
            should_subscribe = entry.is_empty();
            entry.insert("mark_prices");
        });

        if should_subscribe {
            let ws = self
                .get_ws_client_for_product(product_type)
                .context("no WebSocket client for product type")?
                .clone();

            self.spawn_ws(
                async move {
                    ws.subscribe_ticker(instrument_id)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use Linear (perpetual) or Inverse instrument IDs instead of Spot for mark-price subscriptions
  2. Skip mark-price subscription logic for Spot instruments in your strategy configuration
  3. Use last trade price / ticker data for Spot instruments instead of mark prices

Example fix

// before
let instrument_id = InstrumentId::from("BTCUSDT.SBYBIT"); // Spot
data_engine.subscribe_mark_prices(instrument_id);
// after
let instrument_id = InstrumentId::from("BTCUSDT-PERP.SBYBIT"); // Linear
data_engine.subscribe_mark_prices(instrument_id);
Defensive patterns

Strategy: validation

Validate before calling

let instrument = cache.instrument(&instrument_id).expect("instrument not found");
if instrument.asset_class() == AssetClass::SPOT /* or product type Spot */ {
    // skip mark price subscription, use ticker data instead
    return Ok(());
}
data_engine.subscribe_mark_prices(instrument_id)?;

Try / catch

match data_engine.subscribe_mark_prices(instrument_id) {
    Err(e) if e.to_string().contains("Mark prices not available for Spot") => {
        // fall back to quote/ticker data
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling subscribe_mark_prices (via DataEngine.subscribe_mark_prices or SubscribeMarkPrices command) with an instrument_id whose symbol suffix maps to Bybit Spot (e.g. BTCUSDT.SBYBIT resolved to Spot).

Common situations: Configuring a strategy that assumes mark prices exist for all instruments; reusing a data pipeline built for perp/futures symbols with Spot symbols; get_product_type_for_instrument returning Spot from the symbol suffix.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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