nautechsystems/nautilus_trader · error

load_funding_rates not implemented for PostgreSQL cache adap

Error message

load_funding_rates not implemented for PostgreSQL cache adapter

What it means

The PostgreSQL cache adapter implements the CacheDatabaseAdapter trait but load_funding_rates() is an explicit stub: it unconditionally calls anyhow::bail! instead of querying the database. Funding-rate history reads are simply not implemented for this adapter, so any attempt to load them fails immediately.

Source

Thrown at crates/infrastructure/src/sql/cache.rs:1059

                        log::error!(
                            "Failed to send empty trades for instrument {instrument_id}: {e:?}"
                        );
                    }
                }
            }
        });
        Ok(rx.recv()?)
    }

    fn add_funding_rate(&self, _funding_rate: &FundingRateUpdate) -> anyhow::Result<()> {
        anyhow::bail!("add_funding_rate not implemented for PostgreSQL cache adapter")
    }

    fn load_funding_rates(
        &self,
        _instrument_id: &InstrumentId,
    ) -> anyhow::Result<Vec<FundingRateUpdate>> {
        anyhow::bail!("load_funding_rates not implemented for PostgreSQL cache adapter")
    }

    fn add_bar(&self, bar: &Bar) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddBar(bar.to_owned());
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query add_bar to database message handler: {e}")
        })
    }

    fn load_bars(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<Bar>> {
        let pool = self.pool.clone();
        let instrument_id = instrument_id.to_owned();
        let (tx, rx) = std::sync::mpsc::channel();

        tokio::spawn(async move {
            let result = DatabaseQueries::load_bars(&pool, &instrument_id).await;
            match result {
                Ok(bars) => {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Do not read funding rates through the PostgreSQL cache adapter; load them from the source exchange adapter instead
  2. Check the nautilus_trader version/release notes and upgrade if a newer version implements load_funding_rates for the Postgres adapter
  3. Contribute or patch the adapter: implement the query in load_funding_rates alongside the existing add_* implementations in crates/infrastructure/src/sql/cache.rs
  4. Catch the anyhow error and fall back to an alternative data source at the call site

Example fix

// before
let updates = cache.load_funding_rates(&instrument_id)?;
// after
let updates = match cache.load_funding_rates(&instrument_id) {
    Ok(u) => u,
    Err(e) if e.to_string().contains("not implemented") => {
        // fall back to exchange adapter or an empty/partial set
        Vec::new()
    }
};
Defensive patterns

Strategy: fallback

Validate before calling

// feature check before calling
fn postgres_supports_funding_rates() -> bool { false } // current adapter capability
if !postgres_supports_funding_rates() {
    log::warn!("load_funding_rates unsupported on Postgres cache; using exchange source");
}

Try / catch

match cache.load_funding_rates(&instrument_id) {
    Ok(updates) => updates,
    Err(e) => { log::warn!("funding rates unavailable: {e}"); Vec::new() }
}

Prevention

When it happens

Trigger: Calling cache.load_funding_rates(instrument_id) (or any higher-level data path that reads funding rates back) while the backing cache database is the PostgreSQL adapter created via the sql/cache.rs adapter in nautilus_infrastructure.

Common situations: Developers persisting market data to Postgres and later replaying/backtesting from it, assuming funding rates round-trip like bars/quotes do; switching the cache backend from an in-memory or other adapter that supports funding rates to Postgres; feature parity gaps after adopting the SQL adapter.

Related errors


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