nautechsystems/nautilus_trader · error

unsupported Derive public WS channel `{}`

Error message

unsupported Derive public WS channel `{}`

What it means

parse_public_ws_data dispatches Derive public WebSocket messages by channel name (orderbook, trades, ticker/ticker_slim). Any other channel string reaches the final bail. The adapter simply doesn't implement parsing for that public channel yet.

Source

Thrown at crates/adapters/derive/src/websocket/parse.rs:70

///
/// Returns an error when the channel is unsupported or `params.data` does not
/// match the channel payload shape.
pub fn parse_public_ws_data(payload: &WsSubscriptionPayload) -> anyhow::Result<DerivePublicWsData> {
    let channel = payload.channel.as_str();

    if channel.starts_with("orderbook.") {
        return parse_orderbook_msg(payload).map(DerivePublicWsData::Orderbook);
    }

    if channel.starts_with("trades.") {
        return parse_trades_msg(payload).map(DerivePublicWsData::Trades);
    }

    if channel.starts_with("ticker_slim.") || channel.starts_with("ticker.") {
        return parse_ticker_msg(payload).map(|msg| DerivePublicWsData::Ticker(Box::new(msg)));
    }

    anyhow::bail!("unsupported Derive public WS channel `{}`", payload.channel)
}

/// Parses an order book subscription payload.
///
/// # Errors
///
/// Returns an error when `params.data` is not a Derive order book snapshot.
pub fn parse_orderbook_msg(payload: &WsSubscriptionPayload) -> anyhow::Result<DeriveOrderbookMsg> {
    let data = serde_json::from_str::<DeriveOrderbookData>(payload.data.get())
        .context("failed to decode Derive orderbook data")?;
    Ok(DeriveOrderbookMsg {
        channel: payload.channel,
        data,
    })
}

/// Parses a public trades subscription payload.
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Subscribe only to supported public channels: orderbook, trades, ticker/ticker_slim variants
  2. Remove the unsupported channel from the subscription config
  3. If the channel is needed, add a parser and a DerivePublicWsData variant in websocket/parse.rs and route it before the bail
  4. Check the Derive API version for channel renames and update subscription names

Example fix

// before
sub.push("instrument."); // unsupported channel
// after
sub.push("ticker_slim.ETH-PERP"); // supported channel
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED: [&str; 3] = ["orderbook", "trades", "ticker"];
fn channel_supported(ch: &str) -> bool {
    SUPPORTED.iter().any(|p| ch.starts_with(p))
}

Type guard

fn is_supported_public_channel(payload: &WsPayload) -> bool {
    payload.channel.starts_with("orderbook.")
        || payload.channel.starts_with("trades.")
        || payload.channel.starts_with("ticker")
}

Try / catch

match parse_public_ws_data(&payload) {
    Ok(data) => dispatch(data),
    Err(e) if e.to_string().contains("unsupported Derive public WS channel") => {
        log::debug!("ignoring unhandled channel: {}", payload.channel);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Subscribing to a public Derive WS channel the adapter doesn't support (e.g. a newer Derive channel or one outside orderbook/trades/ticker), and receiving frames on it that get routed to parse_public_ws_data.

Common situations: Adding a subscription to a channel available on Derive's API but not mapped in the adapter; Derive renaming/adding channels in a newer API version; typos in channel subscription strings.

Related errors


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