nautechsystems/nautilus_trader · error
Funding rates are only available for Derive perpetual instru
Error message
Funding rates are only available for Derive perpetual instruments (got {instrument_id}) What it means
`request_funding_rates` looks up the requested instrument and, via `anyhow::ensure!`, throws when the instrument is not a `CryptoPerpetual`. Derive funding rates are only defined for perpetuals, so requests for spots/options/futures are rejected.
Source
Thrown at crates/adapters/derive/src/data.rs:1241
params,
));
if let Err(e) = sender.send(DataEvent::Response(response)) {
log::error!("Failed to send Derive trades response: {e}");
}
Ok(())
});
Ok(())
}
fn request_funding_rates(&self, request: RequestFundingRates) -> anyhow::Result<()> {
let instrument_id = request.instrument_id;
let instrument = self
.instruments
.get_cloned(&instrument_id)
.ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
anyhow::ensure!(
matches!(instrument, InstrumentAny::CryptoPerpetual(_)),
"Funding rates are only available for Derive perpetual instruments (got {instrument_id})",
);
let venue_symbol = format_venue_symbol(&instrument_id)?.to_string();
let http_client = self.http_client.clone();
let sender = self.data_sender.clone();
let clock = self.clock;
let client_id = request.client_id.unwrap_or(self.client_id);
let request_id = request.request_id;
let params = request.params;
let start = request.start;
let end = request.end;
let limit = request.limit.map(NonZeroUsize::get);
let start_nanos = datetime_to_unix_nanos(start);
let end_nanos = datetime_to_unix_nanos(end);
let start_ms = start.map(|dt| dt.as_millisecond());
let end_ms = end.map(|dt| dt.as_millisecond());View on GitHub (pinned to 18893faf8b)
Solutions
- Use a Derive perpetual instrument ID such as `ETH-PERP.DERIVE`.
- Check the instrument type before requesting: `matches!(instrument, InstrumentAny::CryptoPerpetual(_))`.
- Filter your instrument list to perpetuals before issuing funding-rate requests.
- For non-perpetual instruments, remove funding-rate logic or use a data source that supports them.
Example fix
// before
client.request_funding_rates(RequestFundingRates::new("ETH-20260926-4000-C.DERIVE", ...))?;
// after
client.request_funding_rates(RequestFundingRates::new("ETH-PERP.DERIVE", ...))?; Defensive patterns
Strategy: validation
Validate before calling
// Rust
if let Some(inst) = cache.instrument(&instrument_id) {
if !matches!(inst, InstrumentAny::CryptoPerpetual(_)) {
return Err(anyhow!("funding rates require a perpetual: {instrument_id}"));
}
} Type guard
fn is_perp(inst: &InstrumentAny) -> bool {
matches!(inst, InstrumentAny::CryptoPerpetual(_))
} Try / catch
if let Err(e) = client.request_funding_rates(req) {
if e.to_string().contains("perpetual instruments") {
// skip or switch instrument
}
} Prevention
- Use `*PERP.DERIVE` instrument IDs for funding-rate requests.
- Filter the cache to perpetuals before bulk funding requests.
- Check instrument kind in strategy config validation.
- Keep options/futures on separate request paths.
When it happens
Trigger: Calling `request_funding_rates` with an `instrument_id` that resolves to a Derive spot, option, or dated-future instrument instead of a perpetual (e.g. "ETH-20260926-4000-C.DERIVE").
Common situations: Configuring a strategy's funding-rate subscription against an options/dated instrument; automated code that iterates all instruments in the cache and requests funding rates for each; users confusing Derive futures with perpetual swaps.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Funding rates only available for perpetuals, not {instrument
- missing trigger price type for Derive trigger order; Derive
- post-only Derive orders only support GTC time in force; rece
- max_fee_per_contract is required
- max_fee_per_contract must be greater than zero
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/110298919f3e3120.
Report an issue: GitHub.