nautechsystems/nautilus_trader · error

Failed to flush database: {e}

Error message

Failed to flush database: {e}

What it means

Raised by RedisCache::flushdb_sync when blocking_recv on the reply channel fails — the reply sender was dropped without a successful result, typically because the background task aborted or the reply channel closed while awaiting the Flush confirmation.

Source

Thrown at crates/infrastructure/src/redis/cache.rs:426

    }

    /// Sends a flush command through the background task channel and blocks
    /// until it completes. Safe to call from any runtime context.
    ///
    /// # Errors
    ///
    /// Returns an error if the command channel is closed or the reply is lost.
    pub fn flushdb_sync(&self) -> anyhow::Result<()> {
        let (reply_tx, reply_rx) = mpsc::sync_channel(1);
        let cmd = DatabaseCommand {
            op_type: DatabaseOperation::Flush(reply_tx),
            key: None,
            payload: None,
        };
        self.tx
            .send(cmd)
            .map_err(|e| anyhow::anyhow!("{FAILED_TX_CHANNEL}: {e}"))?;
        blocking_recv(&reply_rx).map_err(|e| anyhow::anyhow!("Failed to flush database: {e}"))?;
        Ok(())
    }

    /// Retrieves all keys matching the given `pattern` from Redis for this trader.
    ///
    /// # Errors
    ///
    /// Returns an error if the underlying Redis scan operation fails.
    pub async fn keys(&mut self, pattern: &str) -> anyhow::Result<Vec<String>> {
        let pattern = format!("{}{REDIS_DELIMITER}{pattern}", self.trader_key);
        DatabaseQueries::scan_keys(&mut self.con, pattern).await
    }

    /// Reads the value(s) associated with `key` for this trader from Redis.
    ///
    /// # Errors
    ///
    /// Returns an error if the underlying Redis read operation fails.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped error {e} to find why the reply channel closed (panic/abort/disconnect)
  2. Ensure the Redis server is reachable and the background task stays alive for the duration of the flush
  3. Retry the flush after re-establishing the cache connection
  4. Avoid dropping or cancelling the cache task while a flushdb_sync call is in flight
Defensive patterns

Strategy: retry

Validate before calling

// ensure connection is alive before flushing
if !cache.check_connection() {
    anyhow::bail!("redis connection is down; cannot flush");
}

Try / catch

match cache.flushdb_sync() {
    Ok(()) => (),
    Err(e) if e.to_string().starts_with("Failed to flush database") => {
        log::warn!("flush reply lost, retrying: {e:#}");
        cache.flushdb_sync().context("flush retry failed")?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling flushdb_sync; the command is sent successfully, but the background task dies (panic, abort, cancellation) before replying, so blocking_recv returns an error which is wrapped as 'Failed to flush database: {e}'.

Common situations: Redis connection dropping mid-operation, background task being cancelled during shutdown, timeouts or panics in the worker while processing the flush command.

Related errors


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