nautechsystems/nautilus_trader · error · anyhow::Error

Failed to resolve instrument ID for contract {}:{}:{}

Error message

Failed to resolve instrument ID for contract {}:{}:{}

What it means

This error is raised by the Interactive Brokers adapter when resolving a Nautilus instrument ID from an IB contract fails during historical data requests. The adapter queried IB's matching contract details (via get_instrument) but got no match, so it cannot map the contract to a Nautilus instrument ID for bars or ticks requests.

Source

Thrown at crates/adapters/interactive_brokers/src/historical/client.rs:1090

            }
            crate::config::SymbologyMethod::Raw => {
                crate::common::parse::ib_contract_to_instrument_id_raw(contract, Some(venue)).ok()
            }
        };

        if let Some(instrument_id) = parsed {
            return Ok(instrument_id);
        }

        if let Ok(Some(instrument)) = self
            .instrument_provider
            .get_instrument(&self.ib_client, contract)
            .await
        {
            return Ok(instrument.id());
        }

        anyhow::bail!(
            "Failed to resolve instrument ID for contract {}:{}:{}",
            contract.symbol,
            contract.security_type,
            contract.exchange
        );
    }
}

fn retreat_end_datetime(min_ts_nanos: u64) -> Option<Timestamp> {
    let new_end_nanos = min_ts_nanos.saturating_sub(1_000_000); // 1ms
    Timestamp::from_nanosecond(i128::from(new_end_nanos)).ok()
}

fn should_continue_backward_pagination(
    current_end_date: Timestamp,
    current_start_date: Timestamp,
) -> bool {
    current_end_date > current_start_date

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the instrument symbol, security type, and exchange exactly match a contract IB recognizes (test with TWS symbol search).
  2. Use a fully qualified Nautilus instrument ID (e.g. ES.CME) so resolution can short-circuit without an IB lookup.
  3. Check IB Gateway/TWS connectivity and market data subscriptions for the exchange in question.
  4. If the contract is valid but ambiguous, add/correct the exchange field to disambiguate.

Example fix

// before: ambiguous contract
let contract = Contract { symbol: "ES".into(), ..Default::default() };
// after: disambiguated contract
let contract = Contract {
    symbol: "ES".into(),
    security_type: SecurityType::Future,
    exchange: "CME".into(),
    ..Default::default()
};
Defensive patterns

Strategy: validation

Validate before calling

fn contract_is_resolvable(contract: &Contract) -> bool {
    !contract.symbol.is_empty()
        && contract.security_type != SecurityType::Unknown
        && !contract.exchange.is_empty()
}

Prevention

When it happens

Trigger: Calling request_bars or request_ticks with a contract whose symbol, security type, or exchange doesn't match any contract IB returns from reqMatchingSymbols / contract details lookup, or when IB returns no qualifying match.

Common situations: Typos or non-canonical symbols in config (e.g. missing exchange suffix), requesting expired or ill-defined contracts, using exchanges IB historical data doesn't recognize, or symbol ambiguity that yields no unique match.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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