nautechsystems/nautilus_trader · error

Index unknown '{index_key}' on read

Error message

Index unknown '{index_key}' on read

What it means

read_index dispatches on the index key and only recognizes the defined index constants (order, order-emulated, order-inflight, position, positions-open/closed, order-position, order-client mappings). An index key outside that set cannot be mapped to a set or hset read, so it bails. This guards against reading malformed or foreign index keys from Redis.

Source

Thrown at crates/infrastructure/src/redis/queries.rs:986

            .ok_or_else(|| {
                anyhow::anyhow!("Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was {key}")
            })
    }

    async fn read_index(conn: &mut ConnectionManager, key: &str) -> anyhow::Result<Vec<Bytes>> {
        let index_key = get_index_key(key)?;
        match index_key {
            INDEX_ORDER_IDS
            | INDEX_ORDERS
            | INDEX_ORDERS_OPEN
            | INDEX_ORDERS_CLOSED
            | INDEX_ORDERS_EMULATED
            | INDEX_ORDERS_INFLIGHT
            | INDEX_POSITIONS
            | INDEX_POSITIONS_OPEN
            | INDEX_POSITIONS_CLOSED => Self::read_set(conn, key).await,
            INDEX_ORDER_POSITION | INDEX_ORDER_CLIENT => Self::read_hset(conn, key).await,
            _ => anyhow::bail!("Index unknown '{index_key}' on read"),
        }
    }

    async fn read_string(conn: &mut ConnectionManager, key: &str) -> anyhow::Result<Vec<Bytes>> {
        let result: Vec<u8> = conn.get(key).await?;

        if result.is_empty() {
            Ok(vec![])
        } else {
            Ok(vec![Bytes::from(result)])
        }
    }

    async fn read_set(conn: &mut ConnectionManager, key: &str) -> anyhow::Result<Vec<Bytes>> {
        let result: Vec<Bytes> = conn.smembers(key).await?;
        Ok(result)
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the index key matches one of the INDEX_* key formats produced by the writer (crates/infrastructure/src/redis/queries.rs) and correct the key construction
  2. Use the library's index-key builder functions instead of hand-assembling keys
  3. Add the new index kind to the read_index match if it was introduced intentionally

Example fix

// before
let key = format!("{trader}:index:orders-open"); // wrong suffix
// after
let key = index_key(INDEX_POSITIONS_OPEN, &trader); // use library key builder
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_INDEXES: &[&str] = &[INDEX_ORDERS, INDEX_ORDERS_EMULATED, INDEX_ORDERS_INFLIGHT, INDEX_POSITIONS, INDEX_POSITIONS_OPEN, INDEX_POSITIONS_CLOSED, INDEX_ORDER_POSITION, INDEX_ORDER_CLIENT];
if !KNOWN_INDEXES.iter().any(|k| index_key.contains(k)) { return Err(anyhow!("unknown index key {index_key}")); }

Prevention

When it happens

Trigger: Calling read_index (directly or via INDEX collection reads) with an index key string that is not one of the INDEX_* constants — a typo, a hand-built key, or an index type introduced in a different version.

Common situations: Custom tooling that scans Redis and feeds every key back through the cache reader; schema drift between nautilus versions where new index kinds exist but the reader predates them; concatenating index key prefixes incorrectly.

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


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