nautechsystems/nautilus_trader · error
Timeout after {:.1}s awaiting Lighter account streams: pendi
Error message
Timeout after {:.1}s awaiting Lighter account streams: pending={:?} What it means
Raised by the Lighter WebSocket dispatcher when waiting for required account streams (orders, positions, balances) to arrive does not complete within the allotted timeout. The error reports the elapsed seconds and the list of still-pending stream kinds so the developer can see which subscriptions never delivered data.
Source
Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:757
// `all_ready` test and the `.await` is still observed; with
// `notify_waiters` the registration guarantees future notifies
// reach us.
let waiter = self.notify.notified();
tokio::pin!(waiter);
waiter.as_mut().enable();
if self.all_ready() {
log::debug!(
"All Lighter account streams ready in {:.1}s",
start.elapsed().as_secs_f64(),
);
return Ok(());
}
let now = Instant::now();
let elapsed = now.duration_since(start);
if elapsed >= timeout {
anyhow::bail!(
"Timeout after {:.1}s awaiting Lighter account streams: pending={:?}",
timeout.as_secs_f64(),
self.pending(),
);
}
// `elapsed < timeout` is established by the bail above, so the
// subtraction never underflows. Use `saturating_sub` anyway to
// satisfy `clippy::unchecked-time-subtraction`.
let until_timeout = timeout.saturating_sub(elapsed);
let until_warn = next_warn.saturating_duration_since(now);
let wait = until_timeout.min(until_warn);
let _ = tokio::time::timeout(wait, waiter).await;
if !self.all_ready() && Instant::now() >= next_warn {
log::warn!(
"Still awaiting Lighter account streams after {}s: pending={:?}",View on GitHub (pinned to 18893faf8b)
Solutions
- Read pending={:?} in the message to identify which stream(s) never arrived; investigate that specific subscription.
- Verify account_index and API credentials grant access to the private (account) channels.
- Increase the await timeout if the exchange is slow but reachable.
- Test the same subscription manually against the Lighter stream endpoint with wscat to confirm data flows.
- Check Lighter status/announcements for private-channel outages; retry with backoff.
Example fix
// before: waiting for all account streams with a short timeout
wait_for_account_streams(timeout: Duration::from_secs(5)).await?;
// after: longer timeout and explicit pending diagnostics
wait_for_account_streams(timeout: Duration::from_secs(30)).await
.inspect_err(|e| log::warn!("{e}; check subscriptions/auth"))?; Defensive patterns
Strategy: validation
Validate before calling
// before awaiting, confirm credentials can access private channels assert!(creds.account_index > 0); assert!(!creds.api_key.is_empty());
Try / catch
match wait_for_account_streams(timeout).await {
Err(e) if e.to_string().contains("awaiting Lighter account streams") => {
log::error!("{e:#}"); // parse pending={:?} to see missing streams
// retry or fail fast depending on which stream is pending
}
r => r?,
} Prevention
- Verify account_index and API key permissions for private channels
- Use a generous timeout for initial stream snapshots
- Manually test subscriptions with wscat against the stream endpoint
- Monitor exchange status for private-channel incidents
When it happens
Trigger: Subscribing to account streams and awaiting their initial snapshots when one or more streams stay empty past the timeout — subscription rejected by Lighter, auth not accepted for the account, or no data ever published for the requested account.
Common situations: Wrong account_index configured so Lighter never pushes that account's data; API key lacking permission for private channels; network stall on private topics; exchange incident delaying snapshots.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Timeout waiting for account {account_id} to be registered af
- Timeout waiting for account {account_id} to be registered af
- Timeout waiting for account {account_id} to be registered af
- Lighter WebSocket handler did not stop after abort
- Lighter WebSocket initial connection timeout after {} second
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6e1617a56492cd09.
Report an issue: GitHub.