nautechsystems/nautilus_trader · error

Instrument {instrument_id} is expired and no longer availabl

Error message

Instrument {instrument_id} is expired and no longer available for live subscription

What it means

The Polymarket data client refuses live WebSocket subscriptions (book deltas, quotes, trades) for an instrument that is expired and has not been reported open. Once a market's end date has passed and it is not marked open, streaming data for it is considered invalid, so the adapter bails out early. This guards users against subscribing to dead markets and receiving no or misleading data.

Source

Thrown at crates/adapters/polymarket/src/data/mod.rs:352

            ws_open_tokens: self.ws_open_tokens.clone(),
            ws_sub_mutex: self.ws_sub_mutex.clone(),
            ws: self.ws_client.handle(),
            pending_resolutions: self.pending_resolutions.clone(),
            deferred_resolutions: self.deferred_resolutions.clone(),
            subscribe_new_markets: self.config.subscribe_new_markets,
            cancellation_token: self.cancellation_token.clone(),
        }
    }

    fn ensure_live_subscription_allowed(&self, instrument_id: InstrumentId) -> anyhow::Result<()> {
        let now_ns = self.clock.get_time_ns();
        let loaded = self.instruments.load();
        let Some(instrument) = loaded.get(&instrument_id) else {
            return Ok(());
        };

        if is_instrument_expired_and_not_reported_open(instrument, now_ns) {
            anyhow::bail!(
                "Instrument {instrument_id} is expired and no longer available for live subscription"
            );
        }

        Ok(())
    }

    fn ensure_market_data_request_allowed(
        &self,
        instrument_id: InstrumentId,
    ) -> anyhow::Result<InstrumentAny> {
        let loaded = self.instruments.load();
        let instrument = loaded
            .get(&instrument_id)
            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?
            .clone();

        if is_instrument_expired_and_not_reported_open(&instrument, self.clock.get_time_ns()) {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the market's end_date on Polymarket and subscribe to a currently open market instead.
  2. Load instruments via the adapter's instrument provider so expired instruments are detected before subscribing.
  3. Guard the subscription call: skip or re-route when the instrument is expired (see validationCode).
  4. If the market is genuinely still open, refresh instrument definitions so the cached instrument's expiry/status is up to date.

Example fix

// before
client.subscribe_book_deltas(cmd)?;

// after
let instrument = client.instrument(&instrument_id)?;
if is_instrument_expired_and_not_reported_open(&instrument, now_ns) {
    log::warn!("skipping subscription to expired market {instrument_id}");
} else {
    client.subscribe_book_deltas(cmd)?;
}
Defensive patterns

Strategy: validation

Validate before calling

fn can_subscribe_live(instrument: &Instrument, now_ns: UnixNanos) -> bool {
    !is_instrument_expired_and_not_reported_open(instrument, now_ns)
}

Type guard

fn is_open_for_live(instrument: &Instrument, now_ns: UnixNanos) -> bool {
    instrument.expiration_ns() > now_ns.as_u64()
}

Prevention

When it happens

Trigger: Calling subscribe_book_deltas, subscribe_quotes, or subscribe_trades with an InstrumentId whose instrument is_instrument_expired_and_not_reported_open at the current clock time — i.e. the market's expiration has passed and no 'open' status report exists.

Common situations: Strategies configured with hardcoded market IDs that have since expired; long-running nodes that keep re-subscribing after reconnect to markets that ended while the client was down; replaying stale configs from before a market closed.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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