nautechsystems/nautilus_trader · error · anyhow::Error

Failed to send subscription after retries: {e}

Error message

Failed to send subscription after retries: {e}

What it means

After serializing the subscribe message, `handle_subscribe` sends it via `send_with_retry` under the OKX subscription rate-limit key. If all retry attempts fail (connection down, rate limit sustained, sink closed), the error is wrapped with this message and the subscription does not take effect.

Source

Thrown at crates/adapters/okx/src/websocket/handler.rs:542

        for arg in &args {
            log::debug!(
                "Subscribing to channel: channel={:?}, inst_id={:?}",
                arg.channel,
                arg.inst_id
            );
        }

        let message = OKXSubscription {
            op: OKXWsOperation::Subscribe,
            args,
        };

        let json_txt = serde_json::to_string(&message)
            .map_err(|e| anyhow::anyhow!("Failed to serialize subscription: {e}"))?;

        self.send_with_retry(json_txt, Some(OKX_RATE_LIMIT_KEY_SUBSCRIPTION.as_slice()))
            .await
            .map_err(|e| anyhow::anyhow!("Failed to send subscription after retries: {e}"))?;
        Ok(())
    }

    async fn handle_unsubscribe(&self, args: Vec<OKXSubscriptionArg>) -> anyhow::Result<()> {
        for arg in &args {
            log::debug!(
                "Unsubscribing from channel: channel={:?}, inst_id={:?}",
                arg.channel,
                arg.inst_id
            );
        }

        let message = OKXSubscription {
            op: OKXWsOperation::Unsubscribe,
            args,
        };

        let json_txt = serde_json::to_string(&message)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Retry the subscription after reconnecting; most adapters resubscribe on reconnect — verify the connection is active first.
  2. Reduce subscribe burst size or add spacing to stay under OKX's subscription rate limits.
  3. Inspect the inner `{e}` to distinguish rate-limit errors from transport errors.
Defensive patterns

Strategy: retry

Try / catch

// rust
if let Err(e) = subscribe(arg).await {
    if e.to_string().contains("after retries") {
        tokio::time::sleep(Duration::from_secs(1)).await;
        subscribe(arg).await?; // or wait for adapter's resubscribe-on-reconnect
    }
}

Prevention

When it happens

Trigger: Subscribing to a channel while the WebSocket is disconnected, or repeated sends fail within the retry window due to OKX rate limits or a broken socket.

Common situations: Subscribing immediately after connect before the socket is fully established; subscribing to too many channels at once hitting OKX's subscription rate limit; network drop during subscribe.

Related errors


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