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
- Check the market's end_date on Polymarket and subscribe to a currently open market instead.
- Load instruments via the adapter's instrument provider so expired instruments are detected before subscribing.
- Guard the subscription call: skip or re-route when the instrument is expired (see validationCode).
- 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
- Refresh instrument metadata before subscribing after any reconnect.
- Skip or replace expired markets in strategy config at startup.
- Log market end dates during setup and alert on soon-to-expire markets.
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
- Instrument {instrument_id} is expired and no longer availabl
- Subscription error: {e:?}
- Instrument {instrument_id} not found, and `auto_load_missing
- WS user data subscription timed out
- unmapped_in_scope_message("open order", instrument_id, Some(
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0d0dbd4d7e05f71b.
Report an issue: GitHub.