nautechsystems/nautilus_trader · error
Lighter WebSocket handler failed: {error}
Error message
Lighter WebSocket handler failed: {error} What it means
This error is raised by connect_with_cancellation when the spawned Lighter WebSocket handler task terminates with an error while the initial connection is being established. The library joins the handler task after connecting and, if the join outcome is TaskJoinOutcome::Failed, the underlying error is propagated wrapped with this message. It indicates the background task that drives the WebSocket (read loop, auth, subscriptions) died during startup.
Source
Thrown at crates/adapters/lighter/src/websocket/client.rs:439
"Lighter WebSocket initial connection cancelled",
);
if self.is_active() {
log::warn!("Lighter WebSocket already connected");
return Ok(());
}
if let Some(outcome) = finish_task(
&mut self.task_handle,
DISCONNECT_TIMEOUT,
DISCONNECT_TIMEOUT,
)
.await
{
match outcome {
TaskJoinOutcome::Completed(()) | TaskJoinOutcome::Aborted => {}
TaskJoinOutcome::Failed(error) => {
anyhow::bail!("Lighter WebSocket handler failed: {error}");
}
TaskJoinOutcome::Incomplete => {
anyhow::bail!("Lighter WebSocket handler did not stop after abort");
}
}
}
self.signal.store(false, Ordering::Release);
self.initial_connect_cancellation
.store(Arc::new(cancellation_token.clone()));
let (message_handler, raw_rx) = channel_epoch_message_handler();
let cfg = WebSocketConfig {
url: self.url.clone(),
headers: vec![],
heartbeat_interval_secs: Some(HEARTBEAT_INTERVAL.as_secs()),
heartbeat_payload: None,
connect_timeout_ms: Some(self.ws_timeout_secs.saturating_mul(1_000).max(1)),View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the inner `{error}` in the message — it contains the root cause from the handler task; fix that underlying issue first.
- Verify Lighter API key, secret and account index are correct and the key is active on the exchange.
- Check network connectivity / proxy / firewall stability to Lighter's WebSocket endpoint; test with a simple wss client.
- Enable debug logging (log::debug in the handler) to see what the handler task logged before failing.
- Retry connect(); transient network failures resolve on reconnect, and the adapter's reconnect mechanism may also recover it.
Example fix
// before: connect with wrong credentials
let client = factory.create("ws://mainnet.zklighter.elliot.ai/stream", creds)?;
client.connect().await?; // Lighter WebSocket handler failed: auth rejected
// after: verify credentials before connecting
assert!(!creds.api_key.is_empty() && creds.account_index > 0);
let client = factory.create("wss://mainnet.zklighter.elliot.ai/stream", creds)?;
client.connect().await?; Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: verify endpoint reachability and credentials assert!(!creds.api_key.is_empty()); // optionally ping the stream endpoint before connect
Try / catch
match client.connect().await {
Ok(()) => {},
Err(e) if e.to_string().contains("handler failed") => {
log::error!("handler error: {e:#}"); // inspect inner cause
// retry with backoff
}
Err(e) => return Err(e),
} Prevention
- Validate Lighter credentials before startup
- Monitor network stability to the exchange endpoint
- Log handler task errors at source for root-cause triage
- Use the adapter's reconnect mechanism instead of manual reconnect loops
When it happens
Trigger: Calling connect() (via connect_with_cancellation) when the freshly spawned WebSocket handler task returns Err before or during the join — e.g. the underlying websocket connection drops, authentication to Lighter fails inside the handler, or a stream yields an error immediately.
Common situations: Invalid API credentials passed to the Lighter credentials provider; network/proxy dropping the TCP connection right after the handshake; Lighter exchange-side rejection during subscribe/auth; an expired signing key configured in the adapter factory.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Binance Futures data teardown failed: {}
- Binance Spot data teardown failed: {}
- Lighter WebSocket handler did not stop after abort
- Lighter WebSocket initial connection timeout after {} second
- Failed to send SetClient command: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d0317b3c52daa517.
Report an issue: GitHub.