alloy-rs / alloy-rs/alloy

[Bug] WebSocket infinitely retries when server returns invalid protocol

Offen
#3,821 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug
Vorherrschende Sprache
Rust
Sterne
1.3k
Forks
668
Ø Merge
2 T. 2 Std.
Gemergte PRs (30 T.)
29

Beschreibung

### Component

provider, pubsub

### What version of Alloy are you on?

1.7.3

### Operating System

None

### Describe the bug

In this scenario, it retries indefinitely and the error cannot be caught:

1. The WebSocket server is available and connects normally.
2. After a successful connection, it returns a different protocol.

RPCs to reproduce:

- wss://rpc.garnetchain.com
- wss://bahamut-rpc.publicnode.com
- wss://echo.websocket.org

Code to reproduce the issue:
```rust
use alloy::network::AnyNetwork;
use alloy::providers::{Provider, ProviderBuilder, RootProvider, WsConnect};
use alloy::rpc::client::RpcClient;
use anyhow::Result;
use tracing::{debug, error, info};

#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.init();

let rpc_url = "wss://bahamut-rpc.publicnode.com";
debug!("Connecting to RPC: {}", rpc_url);

let ws_connect = WsConnect::new(rpc_url).with_max_retries(2);
let rpc_client = RpcClient::builder().ws(ws_connect).await?;

let provider: RootProvider = ProviderBuilder::default().connect_client(rpc_client);

info!("Connected to RPC successfully");

match provider.get_block_number().await {
Ok(block) => info!("Block: {}", block),
Err(err) => {
error!("{}", err);
}
}

Ok(())
}
```

Output:

```log
2026-03-20T01:59:20.859296Z DEBUG bug01: Connecting to RPC: wss://bahamut-rpc.publicnode.com
2026-03-20T01:59:21.896696Z DEBUG tungstenite::handshake::client: Client handshake done.
2026-03-20T01:59:21.897324Z INFO bug01: Connected to RPC successfully
2026-03-20T01:59:21.897493Z DEBUG alloy_rpc_client::call: sending request method=eth_blockNumber id=0
2026-03-20T01:59:21.897909Z DEBUG request{method_name=eth_blockNumber}: alloy_pubsub::frontend: sending request to backend
2026-03-20T01:59:22.121382Z DEBUG tungstenite::protocol: Received close frame: Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:22.121671Z DEBUG tungstenite::protocol: Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: b"\x03\xf5Internal Error" }
2026-03-20T01:59:22.121950Z ERROR alloy_transport_ws::native: Received close frame with data frame=Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:22.122355Z DEBUG alloy_pubsub::service: Reconnecting pubsub service backend
2026-03-20T01:59:23.065360Z DEBUG tungstenite::handshake::client: Client handshake done.
2026-03-20T01:59:23.065711Z DEBUG alloy_pubsub::service: Draining old backend to_handle
2026-03-20T01:59:23.066016Z DEBUG alloy_pubsub::service: Reissuing pending requests count=1
2026-03-20T01:59:23.066323Z DEBUG alloy_pubsub::service: Re-starting active subscriptions count=0
2026-03-20T01:59:23.291302Z DEBUG tungstenite::protocol: Received close frame: Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:23.291586Z DEBUG tungstenite::protocol: Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: b"\x03\xf5Internal Error" }
2026-03-20T01:59:23.291834Z ERROR alloy_transport_ws::native: Received close frame with data frame=Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:23.292205Z DEBUG alloy_pubsub::service: Reconnecting pubsub service backend
2026-03-20T01:59:24.249028Z DEBUG tungstenite::handshake::client: Client handshake done.
2026-03-20T01:59:24.249362Z DEBUG alloy_pubsub::service: Draining old backend to_handle
2026-03-20T01:59:24.249619Z DEBUG alloy_pubsub::service: Reissuing pending requests count=1
2026-03-20T01:59:24.249854Z DEBUG alloy_pubsub::service: Re-starting active subscriptions count=0
2026-03-20T01:59:24.481691Z DEBUG tungstenite::protocol: Received close frame: Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:24.482009Z DEBUG tungstenite::protocol: Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: b"\x03\xf5Internal Error" }
2026-03-20T01:59:24.482326Z ERROR alloy_transport_ws::native: Received close frame with data frame=Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:24.482801Z DEBUG alloy_pubsub::service: Reconnecting pubsub service backend
2026-03-20T01:59:25.451882Z DEBUG tungstenite::handshake::client: Client handshake done.
2026-03-20T01:59:25.452219Z DEBUG alloy_pubsub::service: Draining old backend to_handle
2026-03-20T01:59:25.452491Z DEBUG alloy_pubsub::service: Reissuing pending requests count=1
2026-03-20T01:59:25.452737Z DEBUG alloy_pubsub::service: Re-starting active subscriptions count=0
2026-03-20T01:59:25.690776Z DEBUG tungstenite::protocol: Received close frame: Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:25.691079Z DEBUG tungstenite::protocol: Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: b"\x03\xf5Internal Error" }
2026-03-20T01:59:25.691323Z ERROR alloy_transport_ws::native: Received close frame with data frame=Some(CloseFrame { code: Again, reason: Utf8Bytes(b"Internal Error") })
2026-03-20T01:59:25.691693Z DEBUG alloy_pubsub::service: Reconnecting pubsub service backend
2026-03-20T01:59:26.682078Z DEBUG tungstenite::handshake::client: Client handshake done.
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.